PDA

View Full Version : pic '877 ADC...PLease HELP !!



Gixxer
- 10th December 2007, 17:20
Hi,

I am fairly new to this whole pic chip thing, and loving it !
I'm building a small (hopefully autonomous) robot and slowly I'm getting close to my goal.
Using a set of Ewave radios and the melabs bootloader, I am able to wirelessly program my pic16f877-04/p, which is pretty cool. All motor control is accomplished using two moded rc servos and an L293D motor driver. Anti-collision will be done using a few Sharp GP2d12 IR range finders. Having the RF modems of course is good for more than just programming. My plan is to be able to tx live onboard telemetry from the robot to my PC or to an RF terminal/user controller and display on a serial LCD.
Should be easy enough, ya right !!! I'm now on day 3 with no luck.
So in order to have any telemetry I first must convert my analog reading to digital, which IS my problem.
I would like to read 0-5v on channels A0,1,2,3 and then serially display on portb.5.
I'm using a 4x20 serial LCD for now hooked up to the PIC, not using wireless until the ADC starts working. In my program below, I'm just looking at two inputs as an experiment, and they do display some value, but nothing correct. I have really tried to get the ADCON settings right, but to no avail. Also, which is better or easier to use, 8 or 10 bit ?

' 10-bit A/D conversion


' Define ADCIN parameters
' Set number of bits in result

define loader_used 1

pause 20

DEFINE ADC_BITS 10
' Set clock source (3=rc)
DEFINE ADC_CLOCK 3
' Set sampling time in microseconds
DEFINE ADC_SAMPLEUS 10

X VAR WORD

A0 VAR WORD ' Create variable to store result
A1 VAR WORD
A3 VAR WORD
' Set PORTA to all input
TRISA = %11111111

ADCON1=4 'SETS PORTA 0,1,3 TO A/D INPUTS

serout portb.5,2,[12] 'clears LCD


Pause 500 ' Wait .5 second

main:

ADCIN 0, A0 ' Read channel 0
PAUSE 100
ADCIN 1, A1 ' " " 1
PAUSE 100
' do something with A0-A2 here



SEROUT portb.5,2,[128,17,22,"BUSS VOLTAGE : ",#a0,145,"vDC"]
SEROUT portb.5,2,[148,"IR DISTANCE : ",#a1,164," cm"]
SEROUT portb.5,2,[168,"TRANCEIVER : "]
SEROUT portb.5,2,[188,"TEMPERATURE : "]
Pause 200 ' Wait .2 secondS
GoTo main
' Do it forever
alarm:
serout portb.5,2,[12,128,"-------ALARM--------"]
serout portb.5,2,[168,"LOW VOLTAGE..: ",#A0/175,185,"vDC"]
PAUSE 200

GOTO MAIN

any help is much appreciated,

JK

mister_e
- 10th December 2007, 17:34
Hi and welcome!
i see 1 small mistake ADCON1 setting. When you use 10 bit resolution, you have to specify to right justify your results, unless, yeah they might be weird.

ADCON1 = %10000100

Now depending of your external impedance the Acquisition/sampling time might be too small. Let's see the worst case... 4MHz, 10K impedance, min acquisition time 11uSec... bah... probably not enough to screw things.

Sounds like an interesting project so far ;)

Gixxer
- 10th December 2007, 18:00
hi,

Thanks alot for your prompt reply mister e ! I will try that code change and see what happens. A few more questions: is any type of pullup/down resistor required on the adc input, or would that cause inaccurate readings ? And according to your calculations, would upping the sample time to 20uSec be better and how do control the input impedance to get the right value? Also, how do I convert my adc "A0" value to volts?

thanks again,
BTW, nice snowy winter so far....Eh !

John

mister_e
- 10th December 2007, 18:16
nice snowy winter so far....Eh !
yeah, for once we have it before march :D


is any type of pullup/down resistor required on the adc input, or would that cause inaccurate readings ?

Not really, but depending what is sending you the voltage... the main concern is more the output impedance your sensor show to the adc. It MUST be lower than the maximum recommended in the datasheet. Adding a simple 0.1uF capacitor is also handy to smooth the results.


And according to your calculations, would upping the sample time to 20uSec be better and how do control the input impedance to get the right value?
well you're really not as this off. 1uSec is nothing, and you're using the slowest conversion clock, so i wouldn't worry to much about that now.


Also, how do I convert my adc "A0" value to volts?
simple maths. 1024=5V
(ADCResult*5)/1024

put 512 as adcresults, and woohoo, you have 2.5 v. but yeah, PBP don't work with floating points... so you need some maths again.. Depending of the accuracy you want, you may use a variant of the above. say
(ADCResult*500)/1024

512 return 250? 2.50 volt.

You need to care about the overflow, */ could be used.

Bellow is a short example of it
http://www.rentron.com/AD_LOG.htm

Acetronics2
- 21st January 2008, 16:41
Hi, Steve

There's something hurting me in the listing ...

"
Quanta CON 1251 ' For 10-bit A/D +Vref = 5V : 5V/1023*256=1.251=Quanta

"

shouldn't it be Quanta = 5v/ [b]1024[/b) * 256 ... ???


That's what all my datasheets tell ... with 5v ref : "code 1023" is 4.99878 v ...

Alain