LPC1768 ADC errors

cancel
Showing results for 
Search instead for 
Did you mean: 

LPC1768 ADC errors

604 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by 2394y80 on Tue Nov 19 11:51:43 MST 2013
I have a board using a LPC1768 which interfaces directly to another board.  I have a problem where the AD values start to show errors when the sister board is powered up.  I have isolated the power supply, but it appears that there still is some noise coming down the data lines with affect the ADC output.  I have tried different chokes on the Vdda/Vssa/Vrefp/Vrefn pins without any effect.

The actual ADC routine runs as an interrupt which scans 7 of the AD pins in a loop, but the ADC error rate is the same outside an interrupt, so I have test code as below. Note that I am using the Keil RTX RTOS and Pclk is 100 MHz, and I I have tied the AD pin to a voltage source so that I can detect and quantify how many reads are inaccurate.
LPC_ADC->ADCR = 0; // Power AD down
 LPC_SC->PCONP |= (1 << 12); // Enable power to AD block
LPC_SC->PCLKSEL0 &= ~(1<<24); // clock 25 MHz
LPC_SC->PCLKSEL0 &= ~(1<<25);
LPC_ADC->ADCR = 7 << 8; // conversion clock = 100 Mhz / 8 [7+1] = 12.5 MHz
LPC_ADC->ADCR |= (1<<21); // PDN = set AD operational
LPC_ADC->ADCR |= (1<<0); // SEL = select AD0.0 to start

int Good = 1;
int Bad = 0;
while(1)
{
LPC_ADC->ADCR |= (1<<24); // START = start conversion now
while (!(LPC_ADC->ADGDR & ( 1UL << 31)))
;  /* Wait for Conversion end       */
int value = (LPC_ADC->ADDR0 >> 4) & 0xFFF;
if((value < 0x580) || (value > 0x5FF))
Bad++;
else
Good++;
double pct = (double)Bad * 100 / (double)Good;
Debug("AN0 = %X good %5d bad %5d %.02f%%", value, Good , Bad, pct);
os_dly_wait(25);
}

The output of the test code is like this:
AN0 = 5D6 good     2 bad     0 0.00%
AN0 = 5D8 good     3 bad     0 0.00%
AN0 = 5D3 good     4 bad     0 0.00%
AN0 = 5D8 good     5 bad     0 0.00%
AN0 = 5D8 good     6 bad     0 0.00%
AN0 = 5D6 good     7 bad     0 0.00%
AN0 = 3FF good     7 bad     1 14.29%
AN0 = 5D7 good     8 bad     1 12.50%
AN0 = 5D5 good     9 bad     1 11.11%
AN0 = 5D8 good    10 bad     1 10.00%
AN0 = 5D7 good    11 bad     1 9.09%
AN0 = 5D9 good    12 bad     1 8.33%
AN0 = 5D7 good    13 bad     1 7.69%
AN0 = 5D5 good    14 bad     1 7.14%
AN0 = 5D7 good    15 bad     1 6.67%
AN0 = 5D8 good    16 bad     1 6.25%
AN0 = 5D6 good    17 bad     1 5.88%
AN0 = 5D6 good    18 bad     1 5.56%
AN0 = 5D9 good    19 bad     1 5.26%
AN0 = 5D7 good    20 bad     1 5.00%
AN0 = 5D7 good    21 bad     1 4.76%
AN0 = 5D8 good    22 bad     1 4.55%
AN0 = 5D6 good    23 bad     1 4.35%
AN0 = FFF good    23 bad     2 8.70%
AN0 = 5D5 good    24 bad     2 8.33%

Over time the error rate is about 2.8%.  Most of the erroneous values are 0xFFF, 0xDFF or similar, so I believe that the ADC is being glitched from noise.  A slow conversion clock gives more errors - about 4% - so I believe that the slower clock gives the ADC core more chance of glitching.  Setting the pin to pull up or pull down makes no difference.

I don't believe the problem is with the software setup / pin configuration since if I start the debugger and manually set up the ADC registers and then keep firing the START bit I get about the same error rate.

The next step would be to re-design the board to give more isolation, but that is going to take some time, and from what I see may not help much.  Any ideas? 
Labels (1)
0 Kudos
5 Replies

88 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by rocketdawg on Wed Nov 20 13:57:59 MST 2013
An interesting observation in AN10974.
JTAG debugging reeks havoc  on ADC sampling.
0 Kudos

88 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pacman on Wed Nov 20 13:09:53 MST 2013

Quote: 2394y80
Well, I thought there were ferrite beads but when I search the part number MLZ1608N1R0L I see they are listed as inductors.  I'll try the parts as you suggested.  I did use a 220nF cap to ground and also try to reduce the input impedance.


The 220nF cap should easily replace a 100nF. ;)
Hopefully the switch to ferrite beads will help.


Quote:
At this point I'm committed to re-designing the PCB and getting another batch made so I'll try to shield the noisy lines as best I can when I re-design the board.


That's what I always do when I have my first batch of prototype boards: I find all the errors I can, and all the possible places that can be improved on, then I get the second batch, if all checks out, I go for production.



Quote:
The good news is that in the worst case I can over sample and filter out the erroneous values via software if I have to, but I'd rather fix the root cause.


That's a good engineer! :)
(and you could leave the filtering code in there, even though the problems are fixed).


Quote:
I did find a lot of references to ADC noise on the mbed part (which uses the LPC1768 as well) so it seems that the ADC is easily glitched in that micro-controller.  See http://mbed.org/forum/bugs-suggestions/topic/1514/ and http://mbed.org/forum/mbed/topic/1866/



Hmm, that does not look good. It could be board-design, though. If you need accuracy, it could perhaps be good to have an option for mounting an external ADC, just in case?

I wonder what makes all that noise possible. Are you running from the internal oscillator, by the way ?
If you are, try patching in a 12MHz clock crystal if possible, and see if it changes anything.


Just one more note; I do not know if I've mentioned it earlier:
Have you tried disabling the ADC-function on all ADC-pins, except the one you're currently using for measuring ?

If the signals should not be short-circuited to GND, you could perhaps try making "high-impedance" pins by changing the pin to GPIO + Open Drain and set it to output ? (I haven't thought much about this, there could perhaps be pitfalls).

I just saw this -I followed a link on the last site you mentioned.
0 Kudos

88 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by 2394y80 on Wed Nov 20 11:05:25 MST 2013
Well, I thought there were ferrite beads but when I search the part number MLZ1608N1R0L I see they are listed as inductors.  I'll try the parts as you suggested.  I did use a 220nF cap to ground and also try to reduce the input impedance.

At this point I'm committed to re-designing the PCB and getting another batch made so I'll try to shield the noisy lines as best I can when I re-design the board.

The good news is that in the worst case I can over sample and filter out the erroneous values via software if I have to, but I'd rather fix the root cause.

I did find a lot of references to ADC noise on the mbed part (which uses the LPC1768 as well) so it seems that the ADC is easily glitched in that micro-controller.  See http://mbed.org/forum/bugs-suggestions/topic/1514/ and http://mbed.org/forum/mbed/topic/1866/
0 Kudos

88 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by Pacman on Wed Nov 20 08:56:01 MST 2013
Strange that people can't send me email anymore. This used to work. Perhaps I'm marked as a spammer, as I wrote a long reply to a blog-post, which was rejected; and I didn't even try to sell anything. ;)

Anyway... It's strange that there are still errors; and you aren't even switching channels.
Unfortunately I can't do much testing in that area here.


Quote:
I have tried different chokes on the Vdda/Vssa/Vrefp/Vrefn pins without any effect


Uhm.. You say "Chokes" - are they 'coils' or are they ferrite beads ?
-If they're coils, try ferrite beads instead; for instance 330R/200mA (BLM18BD331SN1D) or 470R/1A (BLM18PG471SN1D).
Between the ferrite-bead and the pin, connect a 100nF capacitor to GND.

If you have access to a data-logger/-analyzer, you could perhaps check if the input signal changes drastically.
Just in case; I think you've already checked this, as you've isolated the power supply too: Make sure there's enough power available to your microcontroller.

But you mention that noise is coming down the data-lines. Is this noise on the ADC pins, or on other GPIO pins ?

Since it's a prototype PCB... If the noise is coming in on other (GPIO) pins, it might help to run a GND trace on both sides of those data lines as far as you can, and VIAs to a GND plane on the back-side.
Running a GND trace on both sides of your ADC traces plus a GND plane below them might also be a good idea.

I don't know if there is any help in any of those things I mentioned; you probably tried them all, but if there's a chance that I hit anything, it's been worth it. :)

I think I've run completely out of ideas.
[color=#00f]Are there any ADC experts in here, who can assist ?[/color] :)
0 Kudos

88 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by 2394y80 on Tue Nov 19 15:36:24 MST 2013
Update (as I cannot reply to messages it seems)

- I am fairly sure there is not a problem with the PCB / manufacture / soldering - these are prototype boards made by our regular manufacturer of production boards.  I have 9 boards and the 3 that I tried all behaved the same.
- Floating input pins - I've double-checked that pin connect block and everything is either a SF, output or pulled to ground.
- Other ADC pins are all unused, and they have a pull down resistor.

The interesting thing I found today is that the conversion frequency makes a difference:
// LPC_ADC->ADCR = 1 << 8; // 12.5 MHz = 5.5% error rate
// LPC_ADC->ADCR = 2 << 8; // 8.33 MHz = 3.5% error rate
// LPC_ADC->ADCR = 3 << 8; // 6.25 MHz = 8% error rate
LPC_ADC->ADCR = 4 << 8; // 5 MHz = 1.25% error rate
// LPC_ADC->ADCR = 5 << 8; // 4.16 MHz = 2.8% error rate
// LPC_ADC->ADCR = 7 << 8; // 3.125 MHz = 8% error rate
// LPC_ADC->ADCR = 9 << 8; // 2.5 MHz = 1.6% error rate
// LPC_ADC->ADCR = 0xF9 << 8; // 100 khz = 3.5% error rate 


So I have changed the conversion from using an slow conversion clock and firing the next conversion from the interrupt to a timer & match register, which has reduced the error rate from 3.5% to 1.25%
0 Kudos