SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By angelsix
#119066
OK I am sure I came across this issue a while ago and never solved it and now it is back again.

I am using a PIC24F04KA200 and using the ADC to read a simple analogue voltage from a normal 10k pot. That is it. Works perfect when plugged into the programmer, but if I unplug the programmer and power from battery (or even leave the programmer plugged in but disconnect the data programming pin of the ICSP (also the pin I am reading the ADC level from, and cannot change this) then the reading floats.

Powering up without the programmer or as described above, at first the level will remain correct, but as soon as the pot is moved changin the voltage, the value will read randomly. Sometimes it reads correctly but most of the time its noisy.

Plugging it back into the programmer and works 100%.

I have 0.1uF cap on the Vdd and Vss pins and the MCLR set to external with the 10k, 330R and 0.1uF cap as described to do so in the datasheet.

The circuit contains nothing else other than a transistor to come on at a certain level (but that isn't even touched for this test code so won't be doing anything).

The board and code couldn't be simpler yet cannot figure out what is causing it - presumably the code:
Code: Select all
adc.c
================================
#define FCY 4000000UL
#include <p24fxxxx.h>
#include <libpic30.h>

void ADCInitialize(int inputs)
{
	AD1PCFG = inputs ^ 0x1C3F;		// select analog input pin passed in, making all others digital
	AD1CON1 = 0x00E0;                    // automatic
	AD1CSSL = 0; 			// no scanning required
	AD1CON2 = 0; 			// use MUXA, AVss and AVdd are used as Vref+/-
	AD1CON3 = 0x1F00; 		// Tad = 32; Tcy = 500ns (must be >75ns)
	AD1CON1bits.ADON = 1; 	// turn on the ADC
}
int ADCReadAuto(int ch)
{
	AD1CHS = ch; 				// 1. select analog input channel
	AD1CON1bits.SAMP = 1; 		// 2. start sampling
	while (!AD1CON1bits.DONE); 	// 3. wait for the conversion to complete
	return ADC1BUF0; 			// 4. read the conversion result
}

main.c
===========================
void Initialize()
{	
	// 8Mhz clock
	// No clock dividing (default is 4Mhz)
	CLKDIV = 0x3000;

	TRISA = 0;			// All outputs
	TRISB = 0;
	
	PORTA = 0;
	PORTB = 0;

	AD1PCFG = 0x1FFF;	// All digital I/Os (top 3 bits band gaps and vregs)	

	// Set pot pin to ground
	_RB4 = 0;
}

int main()
{	
	Initialize();
	
	// Indicate power-up	
	while (1)
	{
		while (1)
		{
			// Update the current trigger levels
			_TRISB4 = 1;
			ADCInitialize(2);
			unsigned int mRTLevel = ADCReadAuto(2);

			if (mRTLevel > 100)
				BLIPLED();	
		}
	}
}
#119134
That was my thought path.

I have correctly a slight error in the ADC Init that passed in the wrong channel (decimal 2, instead of 1<<2) so now it selects the right channel. Odly it worked when selecting what would of effectively be AN1 and not AN2... but anyway that change didnt fix the issue at hand. I have then gone over every part of the ADC code with a fine eye and made sure everything is spot on and setup right so I will happily say it isn't a setup code issue.

Onto the thing I have since tried.

1. Increase aquisition time to be max (Tcy * 32 then 32Tad so at 8Mhz thats (1/8Mhz * 2 * 32 * 32 = 256us)). I tried it at half that too, no real change to the noise at all, so changed it back to Tcy/2 * 32 = 8us.

2. Added a 10nF cap to the ADC pin and Vss right by the pin - results are iffy. It seems to have definitely improved things, as it seems more settled, but still gets noise. If I toggle the LED on, it causes the voltage to register high, and when off it seems sort of stable, but still easy to get noise. The LEDs resistor (RL) is positioned within 0.3mm of the ADC line so I guess that close on a homemade PCB has noise over to it... guess I never though of that.

Still the question arises even if that were the case why would it be 100% noise free when plugged into the PGD line of the PicKit3... maybe my 10nF cap isn't good enough, and I need to try a few more sizes.

Hopefully it is solvable without a board re-layout and I can just patch it up with caps for this time and correct next time. I am just trying to route out some info on the data line of the PK3 to see if I can just mimic their caps.

Any other suggestions are welcome.

UPDATE: Ok all I can find on the ICSPDAT line is the standard 4.7k pull-down resistor. So I may try that next and see if the noise goes away. Obviously having a 4.7k pull-down on a 10k pot is likely to effect result levels, if it solves the issue I can gradually increase the value the the point where the level isn't effected much.
#119184
Adding the 4.7k resistor made it 85% better, finished with the 10nF cap makes it just like with the debugger plugged in and works without noise :P

I will remake the board next time with the SMD resistor/cap as these are just thru holes and a bit dangly, but proves the solution.
By AndyC_772
#119220
Your PIC has no ground connection.

Unless I'm missing something: your board layout is using a copper flood on the top layer to carry the ground, which is good practice, but it's broken into pieces by the other tracks. The whole area under Q1 and C1 looks to be floating, and that's where the PIC's VSS connection is made.

When you connect the programmer, the PIC is probably grounding through the internal diodes on the programming pins... not too bad provided the programmer is driving a logic 0!

All you need to do is fix the problem on the PCB with a wire and it should work fine, no need for extra R's and C's :)
#119223
It is all commoned, check out the flood going under the pic (top right to its Vss) then the top blue via joins it back to the main ground. Thanks for the observation though. I think my second board will have a little more ground and probably use double-sided copper with the bottom as all ground.
By AndyC_772
#119265
Ah, OK - didn't spot that the track was grounded.

Your decoupling capacitor C1 is quite a way from the PIC, though (in terms of trace length); it might be worth soldering a small (say, 10nF) leaded cap straight to its power pins to see if that helps. The symptoms you're describing do sound like a decoupling, filtering or other noise problem to me.
#119806
Andy,

Thanks for the feedback again. Thought I posted back on this but never did.

The second board as the C1 within 1mm of the pins, all other components closer, and for good measure a 1nF cap and 100k res on each ADC input and all is working good now.

I always underestimate the sensitivity of noise when designing Analogue stuff!

Thanks for the comments.