Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Increasing the sampling rate of ADC in PIC18F4550

Status
Not open for further replies.

Paritoshgiri

Member level 5
Joined
Mar 7, 2010
Messages
83
Helped
1
Reputation
2
Reaction score
0
Trophy points
1,286
Location
Kathmandu
Activity points
1,872
Hi
I am using PIC 18F4550 for ADC. I am using an input voltage range from 1 to 4.5 V and I am getting the digital data in hyperterminal of my PC. I can successfully get a corresponding digital signal of an analog input but when the analog input value changes fast, many values are missed when I see the digital output on hyperterminal. So I need to increase the sampling rate of ADC so that I can see all the values in hyperterminal. I need a sampling rate of atleast 1 KHz. How can I increase the sampling rate so that I can see all the digital output of corresponding analog inputs in a hyperterminal? Please help me with this.

My working code:

Code:
#include <p18f4550.h>
#include <delays.h>

void Read_ADC(void);
void Send_Value (void);

unsigned int adc;
unsigned float result; 
unsigned int voltage;

void main(void)
{
	TRISA  = 0b00000001;
	ADCON0 = 0b00000001;	
		// A/D is ON
	ADCON1 = 0b00001110;	
		// Vref- set to Vss
		// Vref+ set to Vdd
		// AN0 is analog - others are digital
	ADCON2 = 0b10111111;
		// right justify
		// Acq time 20TAD
		// clk Frc
	TXSTA = 0b10100010;
		// 8-bit
		// async
		// low speed (BRGH=0)
	RCSTA = 0b10010000;
	SPBRG = 77;
	
	while (1)
	{	
		Read_ADC();
		Send_Value();
		Delay10KTCYx(240);		//Delay 200 ms
		Delay10KTCYx(240);		//Delay 200 ms
	}

}

void Read_ADC (void)
{
	voltage = 0;		//globally defined as unsigned long
    Delay10TCYx(24);       // Delay for 240TCY allow sampling cap to charge
	ADCON0bits.GO = 1;		//start converting
	while (ADCON0bits.DONE == 1);		//wait for EOC
	voltage = ((unsigned int)ADRESH << 8) | ADRESL;		//combines two bytes into a long int
	result = (float)(voltage * 5)/1023;
	adc = result * 10000;
	//voltage = voltage * 5000;			//Vref is in milliVolts
	//voltage = voltage/1023;			//10 bit ADC
}

void Send_Value (void)
{
	char ch;
	ch = (adc/10000) % 10;		//extract thousands digit
	ch = ch + 48;			// now it is in ASCII

	while (PIR1bits.TXIF == 0);
	{
		TXREG = ch;
	}

	
	while (PIR1bits.TXIF == 0);
	TXREG = '.';		//We need a decimal point

	ch = (adc/1000) % 10;		//extract thousands digit
	ch = ch + 48;			// now it is in ASCII

	while (PIR1bits.TXIF == 0);
	{
		TXREG = ch;
	}
	

	ch = (adc/100) % 10;		//extract hundredth digit
	ch = ch + 48;
	while (PIR1bits.TXIF == 0);
	TXREG = ch;
	

	ch = (adc/10) % 10;		//extract tenth digit
	ch = ch + 48;
	while (PIR1bits.TXIF == 0);
	TXREG = ch;


	ch = adc % 10;		
	ch = ch + 48;
	while (PIR1bits.TXIF == 0);
	TXREG = ch;

	while (PIR1bits.TXIF == 0);
	TXREG = '\n';

	while (PIR1bits.TXIF == 0);
	TXREG = '\r';

	while (PIR1bits.TXIF == 0);
}

The schematics of my circuit:
 

hai... looks like you have configured the conversion clock to RC. But are you sure the RC circuit capacitance is right? For 20MHz, the data sheet recommends 15pF. But you have used 22pF. May be you can change the value and recheck
 

hai... looks like you have configured the conversion clock to RC. But are you sure the RC circuit capacitance is right? For 20MHz, the data sheet recommends 15pF. But you have used 22pF. May be you can change the value and recheck

I didn't have 15pF capacitor so I used 22 pF. So can the sampling rate be increased by using 15pF capacitor? Don't i need to change anything in the code?? Please help...
 

I didn't have 15pF capacitor so I used 22 pF. So can the sampling rate be increased by using 15pF capacitor? Don't i need to change anything in the code?? Please help...

Hai i have not at all worked with PIC controller. Just to help you i have gone through some topics of the data sheet. I think the wrong value of capacitance may give unexpected frequency errors.

you have configured the conversion clock to RC. So it suppose to use the max clock, i think
Are you using hardware/simulator?
 

Hai i have not at all worked with PIC controller. Just to help you i have gone through some topics of the data sheet. I think the wrong value of capacitance may give unexpected frequency errors.

you have configured the conversion clock to RC. So it suppose to use the max clock, i think
Are you using hardware/simulator?
I am using a hardware and its working fine. The only problem is that sampling rate is too low and I want a sampling rate of above 1 KHz. Please help.
 

Last edited:

1KHz is not too high a frequency. Microchip claims that pic18f4520's ADC can go as high as 100K samples per second.The PIC24HJ12GP202 or similar will allow you to sample 10bit AD @ 1.1 msps, In PIC16 it takes less than 40 uS to have a complete 10 bit ADC sample.

https://www.edaboard.com/threads/175050/
Using Analog to Digital Converter
Calculate adc sampling rate for PIC18F4550

Thank you for your reply. I calculate Tad as follows:

Tc = -(C hold)(Ric + Rss + Rs) ln(1/2048) us
Tc = -(22pf) (1 kohm + 2 kohm + 4.7 Kohm) ln(1/2048)
Tc = 1.2916 us

Then,
Tacq = Tamp + Tc + Tcoff
Tacq = 0.2 us + 1.2916 us + 0 (since, Tcoff = 0 for temperature < 25 C)
Tacq = 1.4916 us

Since in my code Tacq = 20Tad
Then, Tad = 1.4916/20 = 0.07458 us

so according to the link https://www.edaboard.com/threads/175050/ Tad must not be less than 1.6us. So can that be the problem? Am i right in calculating the Tad? How to fix this problem? Please help....
 

Is there no way to increase the sampling rate of ADC of PIC 18f4550? Do I need to change my hardware? Please help...
 

Input to ADC should be low impedance (max 10K). No need to put delays for capacitor chaging which is causing slow sample rate. You can add and take average of few samples if you need.
 

Input to ADC should be low impedance (max 10K). No need to put delays for capacitor chaging which is causing slow sample rate. You can add and take average of few samples if you need.
I removed the delay and checked but still I am not getting the desired sample rate. What do you mean by taking average of few samples? How can it be done? Please help...
 

Most probably its communication taking extra time. Just increment a register and send and see time taken to receive 8 bit values in hyperterminal. Run serial communication as an interrupt.
Did you check time taken by calculations in pic? You can send adc results directly to see the change. Baudrate also determine the speed. You can send single sample and do the formatting in computer. If for example four samples are taken then add together and divide by 4 to get average value. This further slows the samples.
CCS :: View topic - Send 10 bits data from ADC by USART Hardware on PIC18F4550
This link shows capabilities of the pic, how 20KHz sample is taken and and lot of other processes are going on.Real-Time Audio Spectrum Analyser - WFFwiki
I found you here.
Someone else might also be interested in the story.
PIC 18F ADC problem
Increasing the sampling rate of ADC in PIC18F4550
 
Last edited:

The delay you provided for the charging of the capacitor slows down the sample rate.

But what really slows down the sample rate is the calculation afterwards. The calculation involving float mathematics and the calculations that follow such as the division really slow you down. You're calling the ADC routine periodically. To really increase the sample rate, you should use an interrupt. After interrupt occurs, move the ADC results to required registers and start another conversion. This will probably give you the fastest ADC sampling as you don't wait before starting/sampling again.

Using the FRC(A/D RC oscillator) also slows you down. Calculate such that you have just enough time for sampling and acquisition. The A/D RC oscillator slows you down.

Hope this helps.
Tahmid.
 

The delay you provided for the charging of the capacitor slows down the sample rate.

But what really slows down the sample rate is the calculation afterwards. The calculation involving float mathematics and the calculations that follow such as the division really slow you down. You're calling the ADC routine periodically. To really increase the sample rate, you should use an interrupt. After interrupt occurs, move the ADC results to required registers and start another conversion. This will probably give you the fastest ADC sampling as you don't wait before starting/sampling again.

Using the FRC(A/D RC oscillator) also slows you down. Calculate such that you have just enough time for sampling and acquisition. The A/D RC oscillator slows you down.

Hope this helps.
Tahmid.

I removed the delay but its still slow. The calculation is still slowing it down so what shall i do to remove this limitation. Also, I have not worked with interrupt before. Does it include performing the ADC in ISR? Please help me out...
 

Also, I have not worked with interrupt before. Does it include performing the ADC in ISR?

Dont perform calculations in the interrupt routine. When interrupt comes, read the value and store in a global variable (also enable user defined flag) and terminate the routine. Once you come out of routine check the flag, if it is enabled then perform the calculation and do further steps.
 

Dont perform calculations in the interrupt routine. When interrupt comes, read the value and store in a global variable (also enable user defined flag) and terminate the routine. Once you come out of routine check the flag, if it is enabled then perform the calculation and do further steps.

Isn't it true that even if we acquire the digital data from ADC very fast using ISR, the time taken for calculation and converting the values to ASCII outside ISR will take much time and limit the use of ISR?
 

No if you get the data from ADC using interrupt and perform calculation outside ISR, it does not affect performance.

A small suggestion: Are you still using the conversion clock to RC? Why dont you try once with the internal clock frequency?
 

Isn't it true that even if we acquire the digital data from ADC very fast using ISR, the time taken for calculation and converting the values to ASCII outside ISR will take much time and limit the use of ISR?

Well, depends.

For example:
You can take ADC readings every 1ms and then carry out calculations in the main routine, but if the calculation takes more than 1ms itself, then there's no point in taking ADC readings so quickly, since you'll either just be loading a value for the next calculation or just acquiring a value that will not even be used.

Hope this helps.
Tahmid.
 

Well, depends.

For example:
You can take ADC readings every 1ms and then carry out calculations in the main routine, but if the calculation takes more than 1ms itself, then there's no point in taking ADC readings so quickly, since you'll either just be loading a value for the next calculation or just acquiring a value that will not even be used.

Hope this helps.
Tahmid.

So how can I find the calculation time? Also, is it possible to do the calculation in PC itself? Will it be faster if I do the calculation in PC? Please help...
 

The delay you provided for the charging of the capacitor slows down the sample rate.

But what really slows down the sample rate is the calculation afterwards. The calculation involving float mathematics and the calculations that follow such as the division really slow you down. You're calling the ADC routine periodically. To really increase the sample rate, you should use an interrupt. After interrupt occurs, move the ADC results to required registers and start another conversion. This will probably give you the fastest ADC sampling as you don't wait before starting/sampling again.

Using the FRC(A/D RC oscillator) also slows you down. Calculate such that you have just enough time for sampling and acquisition. The A/D RC oscillator slows you down.

Hope this helps.
Tahmid.

Can you please tell me what oscillator should I use instead of RC oscillator to speed up the sampling process?
 

Did you try to get ride of these 2 calls to Delay10KTCY(240)?
Just doing the calls you are limiting you convertions/transmitions to something around 2 convertions per second, you are waisting lots of time there.
Why do you need such amount of delay anyway??

Code:
	while (1)
	{	
		Read_ADC();
		Send_Value();
[B]		Delay10KTCYx(240);		//Delay 200 ms
		Delay10KTCYx(240);		//Delay 200 ms[/B]
	}
 
Last edited by a moderator:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top