Author Topic: PIC16f818 ADC not working properly  (Read 1866 times)

0 Members and 1 Guest are viewing this topic.

Offline angelothewolfTopic starter

  • Contributor
  • Posts: 43
PIC16f818 ADC not working properly
« on: January 15, 2018, 07:28:30 pm »
Hello there,

I'm a beginner in PIC programming and I'm trying to run a sort of binary counter using a potentiometer to send a dc signal to the ADC and 7 LEDs to display the output. I'm using MikroC Pro, Proteus 8 Professional and a K150 PIC programmer. I have a PIC 16F818.

The code is:

void main()
{
  unsigned int result;
  OSCCON = 0x70; // set internal clock to 8 MHz
  TRISB = 0x00; //PORTB as output
  TRISA = 0x01; //PORTA.A0 as input

  ADCON1 = 0x0E;
  ADCON0 = 0x00;

  ADCON0.ADON = 1;

  do
  {
   ADCON0.GO_DONE = 1;
   while(ADCON0.GO_DONE)
   result = ADC_Read(0);
   PORTB = result>>3;
   
  }while(1);
}

I'm right shifting the result three times because I only need 7 outputs and the most significant bits gives more accurate results at the output as I change the potentiometer's resistance. The simulation works well. I've set the circuit on a protoboard and I'm having some problems: it's taking a long time for the output to change when I change the potentiometer's resistance; as I change it some values are skiped; the LEDs that are not lightened up are blinking. The circuit is assembled just like in the simulation (image attached). I don't understand why it is taking so long for the output to change, the ADC should be running at 4 MHz as I configured ADCON1 and the internal clock. Also I need the circuit to display every value between 0000000 and 1111111.

Any suggestions?
 

Offline Buriedcode

  • Super Contributor
  • ***
  • Posts: 1611
  • Country: gb
Re: PIC16f818 ADC not working properly
« Reply #1 on: January 15, 2018, 08:02:01 pm »
Use code tags to show your code.  Its the hash - # - symbol .  Or just use [ code ] [ /code ] without the spaces.

Code: [Select]
void main()
{
  unsigned int result;
  OSCCON = 0x70; // set internal clock to 8 MHz
  TRISB = 0x00; //PORTB as output
  TRISA = 0x01; //PORTA.A0 as input

  ADCON1 = 0x0E;
  ADCON0 = 0x00;

  ADCON0.ADON = 1;

  do
  {
   ADCON0.GO_DONE = 1;
   while(ADCON0.GO_DONE); //added this semi colon
   result = ADC_Read(0);
   PORTB = result>>3;
   
  }while(1);
}

Well, it looks like you've configured analogue inputs ok  - AN0 is analogue, rest digital, RA0 is an input.  I would connect MCLR to VCC via a resistor, 10k is fine.

Also note, the output will be binary, not a bargraph. So the lower bits could change constantly making them appear somewhat dim, but the upper bits should be stable.
Aside from the added change, I can't see anything wrong with the code.  What config bits have you set?  In MikroC these are in the projects settings - make sure you have INTOSC selected.
 

Offline woody

  • Frequent Contributor
  • **
  • Posts: 291
  • Country: nl
Re: PIC16f818 ADC not working properly
« Reply #2 on: January 15, 2018, 08:18:38 pm »
Is the 100k pot not a factor 10 too big? I seem to remember that should be between 2.5k and 10k.
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: PIC16f818 ADC not working properly
« Reply #3 on: January 15, 2018, 08:37:18 pm »
-A 100k pot is too large, in order to charge the sampling capacitor to the correct value you will need more time. The datasheet states
Quote
The  maximum  recommended  impedance for analog sources is 2.5 kOhm
there is also a formula to calculate the required sampling time

-i'm pretty sure that 4 MHz violates the ADC minimum clock specification. Yep, TABLE 15-10: A/D CONVERSION REQUIREMENTS.. minimum clock period is 1.6us.

-IIRC ADC_Read(0) auto configure the ADC to read channel 0, starts and end the conversion and returns an 8 bit value (but i should re-read mikroc's documentation to be certain)
 

Offline fcb

  • Super Contributor
  • ***
  • Posts: 2117
  • Country: gb
  • Test instrument designer/G1YWC
    • Electron Plus
Re: PIC16f818 ADC not working properly
« Reply #4 on: January 15, 2018, 08:47:18 pm »
Slow down your conversion clock (top two bits of ADCON0).

Add a capacitor between GND and the analog input, something like a 0.1uF to 1uF will be more than enough to supply current  to the sampling capacitor - or use a buffer amp.
https://electron.plus Power Analysers, VI Signature Testers, Voltage References, Picoammeters, Curve Tracers.
 

Offline angelothewolfTopic starter

  • Contributor
  • Posts: 43
Re: PIC16f818 ADC not working properly
« Reply #5 on: January 16, 2018, 06:12:20 pm »
I didn't know that the minimun sampling period is 1.6us. That means that the maximum sampling frequency is 625kHz. As the clock frequency is 8MHz, I've set the the sampling frequency to be FOSC/16 = 500kHz.
I've also replaced the 10k pot for a 1k trim pot (I don't have a 1k pot right now), I've connected the MCLR to the VCC trough a 1k resistor and I've connected a 100nF cap from GND to RA0 (pin 17 - analog input).
Now it's working well. The LEDs referent to the least significant bits are still too sensitive, but I believe it might be a protoboard problem.
Thank you all for the replies.

The code now is:

Code: [Select]
void main()
{
  unsigned int result;
  OSCCON = 0x70; // set internal clock to 8 MHz
  TRISB = 0x00; // PORTB as output
  TRISA = 0x01; // RA0 as input and others as output

  ADCON1 = 0x4E; // set ADCS2=1 ; RA0 as analog in and others as digital I/O
  ADCON0 = 0x41; // FOSC/16 ; turn ADC on

  do
  {
   ADCON0.GO_DONE = 1;
   while(ADCON0.GO_DONE)
   result = ADC_Read(0);
   PORTB = result>>3;
   
  }while(1);
}
 

Offline picandmix

  • Frequent Contributor
  • **
  • Posts: 395
  • Country: gb
Re: PIC16f818 ADC not working properly
« Reply #6 on: January 17, 2018, 10:10:54 am »
A 10k pot for your adc input should work fine, was your original one old / dirty ?

No need for a resistor in Mclre, just set Mclre to 0 in your Config code. which releases that pin for normal RA5 work.

You do not mention what you are using as the power supply  and how 'clean' it is  ?

Your LSB jitter is due to variations of the Vdd which you are using as the Voltage Reference for the ADC reading.

Check the datasheet and you will see that the Pics also have an inbuilt voltage reference option which should be more stable than Vdd.

You will also find some use a external voltage reference device to give a very stable  voltage.

Depending on the speed of your circuit, you can also improve the displays jitter  by doing several readings and averaging them.
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: PIC16f818 ADC not working properly
« Reply #7 on: January 17, 2018, 10:44:12 am »
No need for a resistor in Mclre, just set Mclre to 0 in your Config code. which releases that pin for normal RA5 work.

I have the habit to disable MCLR and use programming pins as GPIOS only if there's no other solution (when i can't use a bigger part for whatever reason)
If you plan to use ICSP and debug you will have to protect whatever external circuitry to the MCLR pin with at least a series resistor. Then, the MCLR connection from the programmer must go directly to the pin.

This is an old part which requires 14V on MCLR for high voltage programming! (newer parts are fine with 9V)
 

Offline woody

  • Frequent Contributor
  • **
  • Posts: 291
  • Country: nl
Re: PIC16f818 ADC not working properly
« Reply #8 on: January 17, 2018, 11:31:14 am »
Quote
Your LSB jitter is due to variations of the Vdd which you are using as the Voltage Reference for the ADC reading.

I am not so sure about that. If Vdd varies that variation influences the reference the same as the reading so the outcome should be the same. Using a stable reference would make this worse if that stable reference does not also supply the pot.

If this is all on a breadboard then that would be a bigger influence IMO. As you stated averaging the readings makes a lot of sense.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf