PIC16f818 ADC not working properly - Page 1
Forum section: electronics / general

author: angelothewolf
author_rank: Contributor
timestamp: January 15, 2018, 07:28:30 pm
content: 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 MHzTRISB = 0x00; //PORTB as outputTRISA = 0x01; //PORTA.A0 as inputADCON1 = 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?

author: Buriedcode
author_rank: Super Contributor
timestamp: January 15, 2018, 08:02:01 pm
content: Use code tags to show your code. Its the hash - # - symbol . Or just use [ code ] [ /code ] without the spaces.Code:void main(){unsigned int result;OSCCON = 0x70; // set internal clock to 8 MHzTRISB = 0x00; //PORTB as outputTRISA = 0x01; //PORTA.A0 as inputADCON1 = 0x0E;ADCON0 = 0x00;ADCON0.ADON = 1;do{ADCON0.GO_DONE = 1;while(ADCON0.GO_DONE); //added this semi colonresult = 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.

author: woody
author_rank: Frequent Contributor
timestamp: January 15, 2018, 08:18:38 pm
content: Is the 100k pot not a factor 10 too big? I seem to remember that should be between 2.5k and 10k.

author: JPortici
author_rank: Super Contributor
timestamp: January 15, 2018, 08:37:18 pm
content: -A 100k pot is too large, in order to charge the sampling capacitor to the correct value you will need more time. The datasheet statesQuotethere 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)

author: fcb
author_rank: Super Contributor
timestamp: January 15, 2018, 08:47:18 pm
content: 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.

author: angelothewolf
author_rank: Contributor
timestamp: January 16, 2018, 06:12:20 pm
content: 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:void main(){unsigned int result;OSCCON = 0x70; // set internal clock to 8 MHzTRISB = 0x00; // PORTB as outputTRISA = 0x01; // RA0 as input and others as outputADCON1 = 0x4E; // set ADCS2=1 ; RA0 as analog in and others as digital I/OADCON0 = 0x41; // FOSC/16 ; turn ADC ondo{ADCON0.GO_DONE = 1;while(ADCON0.GO_DONE)result = ADC_Read(0);PORTB = result>>3;}while(1);}

author: picandmix
author_rank: Frequent Contributor
timestamp: January 17, 2018, 10:10:54 am
content: 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.

author: JPortici
author_rank: Super Contributor
timestamp: January 17, 2018, 10:44:12 am
content: Quote from: picandmix on January 17, 2018, 10:10:54 amI 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)

author: woody
author_rank: Frequent Contributor
timestamp: January 17, 2018, 11:31:14 am
content: QuoteI 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.