View previous topic :: View next topic |
Author |
Message |
[mAnNaRo]
Joined: 02 Dec 2005 Posts: 28 Location: Italy, Milan
|
A/D Conversion problem... |
Posted: Thu Feb 09, 2006 3:08 pm |
|
|
Code: |
#include <16F877A.h>
#device ADC=10
....
// Setup ADC Port
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL );
....
set_adc_channel(6);
lValue = read_adc();
|
Now, connecting AN6 to +5V I get a value of 2.53V (lValue = 0x208) or using a trimmpot I get values from 0 to 2,53V... any idea??
Alex |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
![](templates/subSilver/images/spacer.gif) |
[mAnNaRo]
Joined: 02 Dec 2005 Posts: 28 Location: Italy, Milan
|
|
Posted: Thu Feb 09, 2006 3:38 pm |
|
|
PCM I've read...
But... I've cutted the code from my long project and pasted in a new. It work fine! because with the same hardware I get 3FE for +5V (on channel 6).
Now... In the long project I use also channels 0 and 1 and they work fine... but adc on channel 6 does't work. What kind of code can interfere with adc on this???
Alex |
|
![](templates/subSilver/images/spacer.gif) |
[mAnNaRo]
Joined: 02 Dec 2005 Posts: 28 Location: Italy, Milan
|
|
Posted: Thu Feb 09, 2006 3:45 pm |
|
|
Another experiment.
The simple code below...
Code: |
void main() {
int16 value;
// Setup ADC Port
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL );
while(TRUE) {
set_adc_channel(0);
value = read_adc();
printf("Value 0 = %LX\r\n", value);
set_adc_channel(1);
value = read_adc();
printf("Value 1 = %LX\r\n", value);
set_adc_channel(6);
value = read_adc();
printf("Value 6 = %LX\r\n", value);
}
}
|
give me the same result as my long project!!! Channel 0 and 1 are correct but channel 6 for +5V give me 0x208! any idea PCM? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 09, 2006 4:05 pm |
|
|
When you change the A/D channel, you should put in a small
delay after that, to allow time for the holding capacitor to charge up.
(This holding capacitor is inside the 16F877A chip).
Add the lines shown in bold below:
Quote: | while(TRUE) {
set_adc_channel(0);
delay_us(20);
value = read_adc();
printf("Value 0 = %LX\r\n", value);
set_adc_channel(1);
delay_us(20);
value = read_adc();
printf("Value 1 = %LX\r\n", value);
set_adc_channel(6);
delay_us(20);
value = read_adc();
printf("Value 6 = %LX\r\n", value);
} |
Also, if one channel doesn't reach the proper value, it could be
that the impedance of the source is too high. What device is driving
channel 6 ? Do you have a series resistor between the device
and the PIC pin for channel 6 ? If so, what value is it ?
In section 11.1 of the 16F877A data sheet, it says:
Quote: | The maximum recommended
impedance for analog sources is 2.5 k. |
Notice that this is quite a bit lower than for the 16F877, which
recommends 10K as the allowable maximum. So I suspect your
problem is due to excessive input impedance for that channel. |
|
![](templates/subSilver/images/spacer.gif) |
[mAnNaRo]
Joined: 02 Dec 2005 Posts: 28 Location: Italy, Milan
|
|
Posted: Thu Feb 09, 2006 4:16 pm |
|
|
Thanx PCM, the problem was the delay_us(20) after channel change!
Alex |
|
![](templates/subSilver/images/spacer.gif) |
crushneck
Joined: 27 Nov 2005 Posts: 29
|
|
Posted: Sat Feb 11, 2006 11:12 am |
|
|
Hello there. Dear PCM programmer. I have a similar project. Just wondering how can i edit it if i wanted to program it whenever a keypad is pressed, the selected output will display on a LCD? |
|
![](templates/subSilver/images/spacer.gif) |
JBM
Joined: 12 May 2004 Posts: 54 Location: edinburgh, Scotland
|
|
Posted: Sat Feb 11, 2006 12:19 pm |
|
|
Crushneck:
Have a look in the examples folder to see how to interface to keypads and LCDs. You could then call set_adc_channel(keypad_data), delay_us(20) and read_adc() to set and read the ADC channel. Then output the data to the LCD using the funcitons defined in the LCD library.
Have a poke around and see how you get on.
-JBM |
|
![](templates/subSilver/images/spacer.gif) |
crushneck
Joined: 27 Nov 2005 Posts: 29
|
|
Posted: Sun Feb 12, 2006 9:45 pm |
|
|
Quote: | Have a look in the examples folder to see how to interface to keypads and LCDs. You could then call set_adc_channel(keypad_data), delay_us(20) and read_adc() to set and read the ADC channel. Then output the data to the LCD using the funcitons defined in the LCD library. |
DEar JBM. how can i put the set_adc_channel(keypad_data); to my codes? I tried to put it but theres an error. Then i try to assume that u mean it this way. Can u check my code? Is this the right way of putting it?COs i did not get the output.
Code: |
#include <lCD420.c>
#include <kbd.c>
void main() {
char k;
long int result;
long int result2;
float adcresult;
float adcresult2;
port_b_pullups(TRUE);
lcd_init();
kbd_init();
SETUP_ADC_PORTS(AN0_AN1_VSS_VREF);
setup_adc(ADC_CLOCK_DIV_8);
while (TRUE) {
lcd_gotoxy(1,1);
printf(lcd_putc, ">>ADC<<", adcresult);
k=kbd_getc();
set_adc_channel(k==1);//press '1' for a voltage output
set_adc_channel(0);
delay_us(20);
result = read_adc();
adcresult = (float)result * (5.0/1024.0);
lcd_gotoxy(1,3);
printf(lcd_putc, "ADC (V): %5.3fV", adcresult);
set_adc_channel(k==2);//press '2' for a current output
set_adc_channel(1);
delay_us(20);
result2 = read_adc();
adcresult2 = (float)result2 * (3.0/1024.0);
lcd_gotoxy(1,2);
printf(lcd_putc, "ADC (I): %5.2fA", adcresult2);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
JBM
Joined: 12 May 2004 Posts: 54 Location: edinburgh, Scotland
|
|
Posted: Mon Feb 13, 2006 4:08 pm |
|
|
Ok, I see where you're going with your code, but there are a few "issues" with it.
At the moment, whenever you evaluate set_adc_channel(k==2), the (k==2) will evaluate to a boolean (true or false) answer. So if k is equal to 2, then that's true - it will pass a 1 to the set_adc_channel funtion, which really isn't what you're looking for. What you need to do is use 2 if statements which test if k is equal to 1 or 2:
Code: |
while (TRUE) {
lcd_gotoxy(1,1); //see note about this bit below
printf(lcd_putc, ">>ADC<<", adcresult);
if(k==1){//press '1' for a voltage output
set_adc_channel(0);
delay_us(20);
result = read_adc();
adcresult = (float)result * (5.0/1024.0);
lcd_gotoxy(1,3);
printf(lcd_putc, "ADC (V): %5.3fV", adcresult);
}
if(k==2){//press '2' for a current output
set_adc_channel(1);
delay_us(20);
result2 = read_adc();
adcresult2 = (float)result2 * (3.0/1024.0);
lcd_gotoxy(1,2);
printf(lcd_putc, "ADC (I): %5.2fA", adcresult2);
}
}
|
Another thing is that the first time you run the loop, there will be no meaningful value in adcresult, simply because you havne't put anything in it yet. You'll probably want to have a look at that.
Let me know how it goes
-JBM |
|
![](templates/subSilver/images/spacer.gif) |
crushneck
Joined: 27 Nov 2005 Posts: 29
|
|
Posted: Tue Feb 14, 2006 12:24 am |
|
|
dear JBM,i still cannot get the oputput i want after using ur given code. My lcd shows only the first line '>>ADC<<' . nothing happen when i press my keypad. Just for ur info, my keypad and LCD is working properly when i use the CCS example for keypad and lcd interface. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 14, 2006 12:38 am |
|
|
Quote: | if(k==1) { //press '1' for a voltage output |
Look in the KBD.C driver file. It has a two-dimensional array
of values that it returns. What type of values does it return ?
What type of value are you comparing it to, in the statement
above ? What should you be comparing it to instead ?
Hint: The answer is in your comment.
2nd hint: Watch the details. |
|
![](templates/subSilver/images/spacer.gif) |
|