Questions about using the A to D
Hi all!
Okay so before some one tells me to read the manual the manual only gives a few "guidelines" and nothing in depth. For example it says the ADC_CLOCK can be a value of 2-5 bits and the default value is 3. It does not say what values 2, 4, and 5 are for. Now I have an 18F1320 and wish to use port b.0 as the input from a sensor putting out 0-5 volts. My best guess is this is what the code should look like?
21 Define ADC_BITS 10 ' Set number of bits in result
22 Define ADC_CLOCK 3 ' Set clock source (3=rc)
23 Define ADC_SAMPLEUS 50 ' Set sampling time in uS
24
25 adval Var word ' Create adval to store result
26
27 TRISB = %11111111 ' Set PORTB to all input
28 ADCON2 = %10000010 ' Set PORTB analog and right justify result
30 mainloop:
31
32
33 ADCIN 0, adval ' Read channel 0 to adval
The other part of this is that the ICD uses port b.1 and port b.4 so would the TRISB statement mess up the IDC?
Thanks in advance for any and all who wish to help educate me.
Best, Ed
Re: Questions about using the A to D
Quote:
The other part of this is that the ICD uses port b.1 and port b.4 so would the TRISB statement mess up the IDC?
no
Quote:
28 ADCON2 = %10000010 ' Set PORTB analog and right justify result
will not set portb analog , and changes adc clock to fosc/32 which contradicts
Quote:
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Quote:
ADCIN 0, adval ' Read channel 0 to adval
ano is porta.1 is this what you mean if so then set adcon1 = %00000001
Re: Questions about using the A to D
Thank you and my wish is to set port B.0 to be the analog input (pin 8). I was not planning on using any of the A ports except for the resonator.
Re: Questions about using the A to D
Quote:
my wish is to set port B.0 to be the analog input (pin 8)
portb.0 is an4 use
ADCIN 4, adval ' Read channel 0 to adval
and set adcon1 to %00010000
there is no need to use tris to set the pin to an input just use adcon1 to make it analogue
Re: Questions about using the A to D
Hi,
Quote:
and set adcon1 to %00010000
Hmm.... I think you've got that backwards...
Looking at the 18F1320 datasheet, ADCON1 defaults to 0 which means that AN0-AN6 are all analog. If AN4 is the ONLY pin to be used as analog you need ADCON1 = %11101111
/Henrik.
Re: Questions about using the A to D
Quote:
Originally Posted by
richard
there is no need to use tris to set the pin to an input just use adcon1 to make it analogue
From the datasheet
Quote:
17.6 Configuring Analog Port Pins
The ADCON1, TRISA and TRISB registers all configure
the A/D port pins. The port pins needed as analog inputs
must have their corresponding TRIS bits set (input). If
the TRIS bit is cleared (output), the digital output level
(VOH or VOL) will be converted
.
Which I read as saying tris has to be set along with adcon1 to make it analogue?
Re: Questions about using the A to D
I stand corrected on both counts
it just goes to show when it comes to pics assume nothing , read data sheet twice . the current pic18f45k20 I'm fooling with says in
19.1 ADC Configuration
The A/D operation is independent of the state of the
ANSx bits and the TRIS bits
and I read it again and yes the tris bit should be set , I misinterpreted that for sure
Re: Questions about using the A to D
Hi,
Yes the TRIS bit needs to be set.
That, however, doesn't meant you actually need to set it since it IS set by default at POR.
/Henrik.
Re: Questions about using the A to D
Thanks Guys, that part makes sense now. If the ICD uses pin 9 (RB1/AN5/TX/CK/INT1) AND PIN 10 (RB4/AN6/RX/DT/KBI0) does that change the ADCON1 pattern?
Re: Questions about using the A to D
have a listen to this about icd setup , I believe if you don't make the pins analogue all should be ok
I have been wong before though
http://support.melabs.com/DT/INTOSC_ICD/INTOSC_ICD.html
Re: A to D reading confusion
Just in case anyone is looking at this, my original external A/D went from 0-4096. The PIC A/D goes from 0-65535! So a divide by 16 makes everything correct!
Re: A to D reading confusion
Hi,
No it doesn't. The ADC in the 18F1320 (as in most PICs) are 10 bits, ie they return a value ranging from 0 to 1023.
However, since the result is 10bits it needs two 8bit registers (bytes) to store the result and depending on how you have the ADC configured it returns the result left or right justified within those two bytes. So, if the input to the ADC is saturated it returns the value 1023, looking at the two registers for the result (ADRESH and ADRESL) it'll will be either (00000011 11111111 = 1023) or (11111111 11000000 = 65472) depending on if you choose to have the result right or left justified.
Check the ADCON2 register.
/Henrik.
Re: A to D reading confusion
Hi Henrik!
Thanks! You are always a good friend and a very big help and I mean that sincerely. The PIC returns a "VOLTS" value of 5824 representing the .441 volts I see on a voltmeter. If I divide 5824 by 16 then the reading would be 364. I changed the code to be /16 rather than /10. Using a conversion chart where 5.00 volts equals 4096 then 364 is really close. The sensor does vary a little about every 28 second it will read either + or - 4 using the divide by 16 value or 5824 then 5888 without the divide. Not sure why this happens, it's not temperature related and the reference port and sensor port are connected together with a piece of tubing. I do not know how to display the value in the ADCON2 register to do a check.
Best, Ed
Re: A to D reading confusion
Hi Ed,
Your previous ADC had a resolution of 12 bits, ie a value ranging from 0 to 4095.
The PIC ADC has a resolution of 10 bits, ie a value ranging from 0 to 1023 in "steps" of 1 (0, 1 ,2 ,3, 4....) or from 0 to 65472 in "steps" of 64 (0, 64, 128, 192, 256...)
If you divide 65472 by 16 you'll get 4092 which is pretty close to 4095 - that's the reason it "works" for you. And if you divide the "step size" of 64 by 16 you'll get 4 so when you see you're value "bouncing" +/- 4 counts it's really only "bouncing" +/- 1 LSB which is kind of expected.
Try setting ADCON2.7 = 1 to right justify the result and see if you'll get a result from 0 to 1023 with "steps" of 1 instead. If needed, you can then get more resolution by oversampling. Take 16 readings, add them all up and divide by 4 to go from 10 bits to a "psuedo resolution" of 12 bits - for example.
I'm not saying what you're doing is wrong - as long as it works for you I'm happy :-)
I just wanted to clarify for you and others that might find your comment about the ADC is going from 0-65535 that the resolution of the ADC is NOT 16bits which you might think it is when reading your post.
/Henrik.
Re: A to D reading confusion
Interesting explanation Henrik. I was trying to work out how 0-65535 was achieved knowing that the PIC ADC was 10 bit. Reading the datasheet
Quote:
The module has five registers:
• A/D Result High Register (ADRESH)
• A/D Result Low Register (ADRESL)
• A/D Control Register 0 (ADCON0)
• A/D Control Register 1 (ADCON1)
• A/D Control Register 2 (ADCON2)
The ADCON0 register, shown in Register 17-1,
controls the operation of the A/D module. The
ADCON1 register, shown in Register 17-2, configures
the functions of the port pins. The ADCON2 register,
shown in Register 17-3, configures the A/D clock
source, programmed acquisition time and justification.
I was puzzling over the last word "justification" and the effect it would have. Now I know.
Re: A to D reading confusion
Hi Steve, Ed,
Just to clarify further, it can never return 65535 no matter how you configure it.
It'll look like this, where x is the actual conversion result returned by the 10 bit ADC:
Code:
ADRESH ADRESL
xxxxxxxx xx000000 Left justified, ADCON2.7 = 0 (default)
000000xx xxxxxxxx Right justified, ADCON2.7 = 1
With left justification the two most significant bits in ADRESL are the two least significant bits of the 10 bit result.
With right justification the two least significant bits in ADRESH are the two most significant bits of the 10 bit result.
If you have the ADC set to left justification but look at the result as a "normal" 16 bit value each LSB of the ADC result will change the 16 bit value by 64 since the LSB of the ADC result is aligned with ADRESL.6.
So, with left justification and the ADC saturated the maximum value it can return is 65472 since the 6 least significant bits in ADRESL will be 0.
/Henrik.
Re: A to D reading confusion
Hi Henrik!
Again thank you! You are correct. I connected a 10K resistor from the +5v to the ADC input pin and got 65472! Probably should have done that first! Just wondering, any way to eliminate the "bounce"?
Ed
Re: A to D reading confusion
Hi Ed,
Quote:
Just wondering, any way to eliminate the "bounce"?
Make sure that VRef is stable.
In this case I think you're using Vdd as Vref so proper bypassing right at the supply pin(s) of the PIC. At Vdd/VRef=5V a difference of 4.88mV will make the ADC result "jump" a LSB. So any ripple larger than +/-5mV on the supply will be reflected on the readings.
Make sure that you feed the ADC input from a low(ish) impedence circuit.
If your sensor has a high output impedence you may need to buffer the signal with a OP-amp or whatever. Filter the sensor output then feed it to the buffer then to the ADC input.
Or you can simply try throwing a 10-100nF capacitor right on the ADC input pin....
Or just filter it in software.... which, again, will allow you to oversample and get more resolution (if needed).
Remember, you're seeing a "bounce" of 4 (or 64 actually) but in reallity it's only a single LSB - and that's pretty normal.
/Henrik.