• AVR Freaks

AnsweredHot!PIC16F877A ADC reads strange with HIGH potentiometer values

Page: 12 > Showing page 1 of 2
Author
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
2019/11/20 16:24:06 (permalink)
0

PIC16F877A ADC reads strange with HIGH potentiometer values

Hello,
 
I'm working with PIC16F877A to test the adc, but I noticed with higher pot values, the adc reads really strange.
 
It only reads low adc values on the lcd until I reach the max pot value, then the pic reads like 966 adc with 2k to 50k ohms
 
with 200k ohms it even worse, it reads 500 adc max.
 
but when I use 100 ohms, it reads perfectly fine except it doesn't give the real max source voltage; like, if source voltage is 5.075V then with 100 ohms I measure 4.9V on adc input pin. Otherwise it works ok.
 
 
So what's the problem with high potentiometer values ?
#1
ric
Super Member
  • Total Posts : 24639
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/20 16:29:12 (permalink) ☄ Helpfulby eagle1 2019/11/20 16:45:12
+1 (1)
eagle1
So what's the problem with high potentiometer values ?

Violating the datasheet specifications.
http://ww1.microchip.com/...oc/39582C.pdf#page=130
Section "11.1A/D Acquisition Requirements"

The maximum recommended impedance for analog sources is 2.5 k

 
Also, you did not show your code. What "acquisition time" are you allowing?
 
You can reduce the effective impedance of the pot by placing a small capacitor in parallel with the signal.
Try 100nF or 1uF.
 
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#2
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/20 16:46:59 (permalink)
0
This is my code:
void adc_init(void){
    ADCON0 = 0b00000001; // ADC ON
    ADCON1 = 0b10000000; // right justified result
    ADRESL = 0;
    ADRESH = 0;
}

uint16_t read_adc(uint8_t ch){ 
    ADCON0 |= (ch << 3); // shift channel number
    __delay_ms(2); // charge hold capacitor
    GO_DONE = 1; // START ADC
    while(GO_DONE); // wait until process is finished
    return((ADRESH<<8) + ADRESL);
}

void adc_call_function(uint8_t channel){
    adc_val = read_adc(channel);
    sprintf(adc_val_arr,"%d",adc_val);
    lcd_string_xy(0,1,"ADC value: ");
    lcd_string_xy(1,11,adc_val_arr); 
}

 
I'm running the PIC with 4MHz oscillator.
 
I should place the capacitor between the pin and ground, is that correct?
post edited by eagle1 - 2019/11/20 16:48:18
#3
ric
Super Member
  • Total Posts : 24639
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/20 16:52:54 (permalink) ☼ Best Answerby eagle1 2019/11/20 17:49:22
+2 (2)
ok, your code has 2ms acquisition time, which is plenty (20us is usually enough).

I should place the capacitor between the pin and ground, is that correct?

Yes. Make sure the ground connection is close to the PIC's ground pin, or you will be injecting ground noise into the reading.
 
Note, your code to select the channel will fail when you select a different channel, as you are setting bits with the "|=" operator, but never clearing them.
It's safer to let the compiler do the work:
ADCON0bits.CHS = ch;

 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#4
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/20 17:49:38 (permalink)
0
Thanks a lot :)
#5
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/20 18:04:17 (permalink)
0
Also how about this code for selecting the channels?
uint16_t read_adc(uint8_t ch){
    ADCON0 &= ‭0b11000111‬;  // masking out the channel bits
    ADCON0 |= (ch << 3); // shift channel number
    __delay_us(20); // charge hold capacitor
    GO_DONE = 1; // START ADC
    while(GO_DONE); // wait until process is finished
    return((ADRESH<<8) + ADRESL);
}

post edited by eagle1 - 2019/11/20 18:05:20
#6
ric
Super Member
  • Total Posts : 24639
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/20 18:48:35 (permalink) ☄ Helpfulby eagle1 2019/11/21 10:02:51
+2 (2)
Yes, this will work
    ADCON0 &= ‭0b11000111‬;  // masking out the channel bits
    ADCON0 |= (ch << 3); // shift channel number

However this will probably generate exactly the same assembly output, but is much more readable
ADCON0bits.CHS = ch;

It's also more portable, meaning you can use the same code on another PIC16 device, and it will still work even if that PIC has the CHS bits in a different position in the register.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#7
jtemples
عُضْوٌ جَدِيد
  • Total Posts : 11432
  • Reward points : 0
  • Joined: 2004/02/13 12:31:19
  • Location: Southern California
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/20 21:20:54 (permalink) ☄ Helpfulby eagle1 2019/11/21 10:07:39
+2 (2)
...and it's readable, and you know it's correct without having to go back to the data sheet to make sure you got the right bit positions.
#8
1and0
Access is Denied
  • Total Posts : 10005
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/20 21:41:09 (permalink) ☄ Helpfulby eagle1 2019/11/21 10:06:52
+2 (2)
...and it's more efficient.
 
But if you insist on inefficiency and less readable, then at least do this:
ADCON0 &= ~_ADCON0_CHS_MASK; // masking out the channel bits
ADCON0 |= (ch << _ADCON0_CHS_POSN); // shift channel number

 
#9
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 10:06:23 (permalink)
0
ric
Yes, this will work
    ADCON0 &= ‭0b11000111‬;  // masking out the channel bits
    ADCON0 |= (ch << 3); // shift channel number

However this will probably generate exactly the same assembly output, but is much more readable
ADCON0bits.CHS = ch;

It's also more portable, meaning you can use the same code on another PIC16 device, and it will still work even if that PIC has the CHS bits in a different position in the register.
 


That's interesting ! Knowing it's the same assembly output. I'm doing the mask to do different things at once, but I think in this case it's suitable.
#10
1and0
Access is Denied
  • Total Posts : 10005
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 10:11:16 (permalink) ☄ Helpfulby eagle1 2019/11/21 10:39:42
+2 (2)
eagle1
That's interesting ! Knowing it's the same assembly output. I'm doing the mask to do different things at once, but I think in this case it's suitable.

The bitfield version produces better assembly output.
#11
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 10:39:12 (permalink)
0
1and0
ADCON0 &= ~_ADCON0_CHS_MASK; // masking out the channel bits


But I didn't get how this should work !
#12
NKurzman
A Guy on the Net
  • Total Posts : 18061
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 10:45:36 (permalink) ☄ Helpfulby eagle1 2019/11/21 10:51:43
+2 (2)
eagle1
1and0
ADCON0 &= ~_ADCON0_CHS_MASK; // masking out the channel bits


But I didn't get how this should work !
The ~ inverts all the bits in  _ADCON0_CHS_MASK  the AND does the Rest.


#13
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 10:51:13 (permalink)
+1 (1)
1and0
 
The bitfield version produces better assembly output.



bitfield is a very good strategy I use it almost all the time in my PIC programming !
#14
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 10:54:49 (permalink)
0
NKurzman
The ~ inverts all the bits in  _ADCON0_CHS_MASK  the AND does the Rest.

ok so does that mean _ADCON0_CHS_MASK is already defined in xc8 ?
#15
ric
Super Member
  • Total Posts : 24639
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 12:13:36 (permalink) ☄ Helpfulby eagle1 2019/11/21 13:09:59
+2 (2)
eagle1
NKurzman
The ~ inverts all the bits in  _ADCON0_CHS_MASK  the AND does the Rest.

ok so does that mean _ADCON0_CHS_MASK is already defined in xc8 ?

Yes.
XC8 contains a specific header file for every PIC it supports.
This is included for you via xc.h.
If you have the latest version of XC8, have a look in
C:\Program Files (x86)\Microchip\xc8\v2.10\pic\include\pic16f877a.h
and you will see all the definitions for the SFRs and various bits within them.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#16
NKurzman
A Guy on the Net
  • Total Posts : 18061
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 12:20:57 (permalink) ☄ Helpfulby eagle1 2019/11/21 13:10:17
+1 (1)
eagle1
NKurzman
The ~ inverts all the bits in  _ADCON0_CHS_MASK  the AND does the Rest.

ok so does that mean _ADCON0_CHS_MASK is already defined in xc8 ?



Yes, it defined in XC8.
#17
1and0
Access is Denied
  • Total Posts : 10005
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 12:48:52 (permalink) ☄ Helpfulby eagle1 2019/11/21 13:10:39
+1 (1)
For your PIC device,
 
_ADCON0_CHS_MASK = 0x38 = 0b00111000
 
so complement it and you'll get
 
~_ADCON0_CHS_MASK = 0b11000111
 
Edit: Actually you will get a 16-bit value, but the upper byte is not used for your case.
post edited by 1and0 - 2019/11/21 12:51:13
#18
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 13:17:03 (permalink)
0
1and0
For your PIC device,
 
_ADCON0_CHS_MASK = 0x38 = 0b00111000
 
so complement it and you'll get
 
~_ADCON0_CHS_MASK = 0b11000111
 
Edit: Actually you will get a 16-bit value, but the upper byte is not used for your case.


Yep thank you very much ! wow the mask is really smart.
#19
eagle1
Super Member
  • Total Posts : 396
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: PIC16F877A ADC reads strange with HIGH potentiometer values 2019/11/21 13:25:04 (permalink)
0

wow, now I can program my Arduino boards too with MPLAB X ? that would be very interesting. but how about the hardware, would the Arduino usb be recognized with MPLAB IPE ?
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5