EmbeddedRelated.com
Forums

Glitches with ADC12 internal temperature sensor

Started by John Pitney October 6, 2012
On 08.10.2012 18:25, lslonim2 wrote:
> I've used the MSP430 series for 6 years, and have always found the ADC
> to be noisy. I average at least 16 samples before using, and often it
:

My hint is to use median (15 samples) instead of average. That's what
I'm actually using and my results are quite satisfying.

Hardy

Beginning Microcontrollers with the MSP430

A very important element seems to be missing from this discussion: antialias filtering.

It is absolutely essential to low pass filter the input to the ADC so that frequencies at 1/2 the sample rate and above are adequately suppressed. In the case of a 12 bit ADC this means -72dB of filtering at Nyquist. That's an 11 pole filter if you set the corner at 1/2 Nyquist (i.e. 1/4 the sampling rate). If you ignore this you will get the crappy results you deserve no matter what device you use. Averaging samples will not correct the problem. It will only eliminate some of the aliased signal. Signals 1 Hz above Nyquist will appear in the output at 1 Hz.

Averaging only works if you sample much faster than the signal you want and then decimate after averaging. But you still need an adequate antialias filter at the actual sampling rate. And averaging can still leave plenty of stopband ripple to be aliased in the decimation. A properly designed low pass digital filter will provide better results. Triangular weighted averaging will be better than boxcar weights, but not as good as a proper filter.

Everything present on the input to the ADC matters. Just because the sensor output is low bandwidth does not mean that the ADC input is low bandwidth. In the vicinity of digital circuits running at several MHz there is lots of low level, high frequency noise. If this is not filtered out, it will appear on the ADC output as low frequency noise.

It's very hard to say what the internal temperature sensor input to the ADC has. I suspect nothing as it's probably not expected to be a high precision measurement. While thermal mass would make the thermistor output low frequency, that does not preclude coupling noise above Nyquist from other parts of the chip.

Have Fun!
Reg





--- In m..., Reginald Beardsley wrote:
>
>
> Averaging only works if you sample much faster than the signal you want and then decimate after averaging.

That's the case when measuring temperature, which is almost DC, and the sampling frequency is several dozen kHz. Basically, everything that's not DC is noise and can be averaged out.

I agree. I am only using this to measure DC voltages, so averaging is the way to go. It would be impossible for me to make a lowpass filter that was quiet down to the microvolts in a real system.

Lloyd

--- In m..., "distantship101" wrote:
>
>
> --- In m..., Reginald Beardsley wrote:
> >
> >
> > Averaging only works if you sample much faster than the signal you want and then decimate after averaging.
>
> That's the case when measuring temperature, which is almost DC, and the sampling frequency is several dozen kHz. Basically, everything that's not DC is noise and can be averaged out.
>

If you've not actually calculated the filter response of averaging you should. There are several free MATLAB clones that will do this for you.

And yes, eliminating microvolt level noise is hard, especially in an MCU design. Consider the requirements for the 24 bit delta-sigma version of the 430, -144dB at Nyquist. That's seriously hard to do. It's actually a strong argument for as many poles of analog filter as you can reliably build, followed by oversampled conversion and additional digital filtering and decimation.

Have Fun!
Reg





Just a shoot in the dark. Could it be some other activities causing the glitch? For example the UART?

You could try stop all other activities, do ADC only, and save a few dozens of consecutive results in RAM. Then resume other activities and send the saved results via UART. Do you still see abnormal results?

--- In m..., John Pitney wrote:
>
> Hi all,
>
> I'm trying out the internal temperature sensor on an MSP430F449 with the
> ADC12. Most of the samples I get are within a few counts of the median,
> but some, maybe less than 10%, are 15 counts off, usually low. The MSP430
> is on an Olimex development board, which seems to have all the recommended
> power and reference capacitors. I suspect I'm doing something wrong in my
> code, so I'd appreciate any pointers on where I'm going wrong.
>
> //*****************************************************************************
> // Olimex MSP430F449-STK
> //*****************************************************************************
> // Compiled with msp430-gcc-4.5.3 -Os -mmcu=msp430f449
> // Example output (note 0x06AF and 0x06B5)
> // 06C7 06C6 06C6 06C7 06C6 06C6 06C5 06C6
> // 06C6 06C6 06C6 06C6 06C6 06AF 06C7 06C6
> // 06C5 06C6 06B5 06C6 06C6 06C8 06C6 06C6
> // 06C6 06C6 06C8 06C6 06C6 06C8 06C6 06C5
>
> #include
> #include
> #include #define N_RESULTS 8
> static uint16_t ADCresult[N_RESULTS];
>
> void tx(char c);
> size_t tx_string(char * Buf, size_t Bufsize);
> void itoa16(uint16_t x, char *s);
>
> void main(void)
> {
> volatile int i;
> char s;
> WDTCTL = WDT_ADLY_250; // 250ms interval timer
> FLL_CTL0 |= XCAP18PF; // Configure load caps
> IE1 |= WDTIE; // Enable WDT interrupt
> P4SEL |= 0x01 | 0x02; // P4.0,1 = USART1 TXD/RXD
> ME2 |= UTXE1 + URXE1; // Enable USART1 TXD/RXD
> U1CTL |= CHAR; // 8-bit character
> U1TCTL |= SSEL1; // UCLK = SMCLK
> U1BR0 = 0x6D; // 1MHz 9600
> U1BR1 = 0x00; // 1MHz 9600
> U1MCTL = 0x03; // modulation
> U1CTL &= ~SWRST; // Initialize USART state
> machine
> IE2 |= URXIE1; // Enable USART1 RX interrupt
> P4DIR |= 0x01; // P4.0 output direction
> ADC12CTL0 = ADC12ON+REFON+REF2_5V+MSC+SHT0_10;
> ADC12CTL1 = SHP+CONSEQ_1+ADC12DIV_7;
> ADC12MCTL0 = INCH_10+SREF_1;
> ADC12MCTL1 = INCH_10+SREF_1;
> ADC12MCTL2 = INCH_10+SREF_1;
> ADC12MCTL3 = INCH_10+SREF_1;
> ADC12MCTL4 = INCH_10+SREF_1;
> ADC12MCTL5 = INCH_10+SREF_1;
> ADC12MCTL6 = INCH_10+SREF_1;
> ADC12MCTL7 = INCH_10+SREF_1+EOS;
> ADC12IE = 1 << 7;
> ADC12CTL0 |= ENC;
> for(;;) {
> char buf[5];
> ADC12CTL0 = ADC12ON+REFON+REF2_5V+MSC+SHT0_10;
> ADC12CTL1 = SHP+CONSEQ_1;
> ADC12CTL0 |= ENC;
> for(i=0; i < 0x7200; i++) {
> } // no-op delay for reference stabilization
> ADC12CTL0 |= ADC12SC; // start conversion
> _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
> // ADC12CTL0 &= !ADC12ON; // commented out, but problem
> remains
> s = ' ';
> for(i = 0; i < N_RESULTS; i++) {
> itoa16(ADCresult[i], buf);
> tx_string(buf, 4);
> tx(s);
> }
> s = '\n';
> tx(s);
> _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
> }
> }
>
> // Watchdog Timer interrupt service routine
> __attribute__((interrupt(WDT_VECTOR)))
> void watchdog_timer(void)
> {
> _BIC_SR_IRQ(LPM0_bits); // Back to active mode
> }
>
> __attribute__((interrupt(ADC12_VECTOR)))
> void ADC12ISR(void) {
> ADCresult[0] = ADC12MEM0;
> ADCresult[1] = ADC12MEM1;
> ADCresult[2] = ADC12MEM2;
> ADCresult[3] = ADC12MEM3;
> ADCresult[4] = ADC12MEM4;
> ADCresult[5] = ADC12MEM5;
> ADCresult[6] = ADC12MEM6;
> ADCresult[7] = ADC12MEM7;
> _BIC_SR_IRQ(LPM0_bits); // Back to active mode
> }
>
> Thanks,
> John
>
>

One other thing I've discovered with the MSP430F149 (the only one I ever
used analog on) was that the standard Ti decoupling scheme of DVCC and
AVCC linked and decoupled with a 10uF and a 100nF is not optimal. I
found better performance by separating the supplies at the supply source
and also adding some additional filtering to the AVCC line, then
decoupling each supply locally with 10uF/100nF for the DVCC line and a
2u2/10nF on the AVCC line. this allowed me to use smaller ceranics for
the AVCC line.

Another thing I have found useful is to use a decimation filter. The
simplest one I use oversamples 6 times then rejects highest and lowest
readings and averages the remaining 4. Aliased noise in my experience
tends to be spiky in nature, so this method removes those spikes,
whereas averaging tends to produce humps around the spike.

Al
On 10/10/2012 12:00 AM, Reginald Beardsley wrote:
> If you've not actually calculated the filter response of averaging you should. There are several free MATLAB clones that will do this for you.
>
> And yes, eliminating microvolt level noise is hard, especially in an MCU design. Consider the requirements for the 24 bit delta-sigma version of the 430, -144dB at Nyquist. That's seriously hard to do. It's actually a strong argument for as many poles of analog filter as you can reliably build, followed by oversampled conversion and additional digital filtering and decimation.
>
> Have Fun!
> Reg
>
>
>
>
perhaps that should be the next peripheral that Ti include. A
programmable cut off low pass filter. It would be an excellent, and
perhaps obvious peripheral for any device with an A/D, and something I
don't think anyone else does as a peripheral for a micro, although they
are available as stand alone parts.

Al
On 10/10/2012 12:00 AM, Reginald Beardsley wrote:
> If you've not actually calculated the filter response of averaging you should. There are several free MATLAB clones that will do this for you.
>
> And yes, eliminating microvolt level noise is hard, especially in an MCU design. Consider the requirements for the 24 bit delta-sigma version of the 430, -144dB at Nyquist. That's seriously hard to do. It's actually a strong argument for as many poles of analog filter as you can reliably build, followed by oversampled conversion and additional digital filtering and decimation.
>
> Have Fun!
> Reg
>
>
>
>
It's a bit surprising that they don't offer one already.   It would save a lot of hassle and board space. It probably needs some care to be able to turn it on and off to keep power drain low.  The high clock rate for a switched capacitor filter could also be a significant power drain, forcing TI to raise their power drain specs which they might not like doing.  Data sheets are a bit of an exercise in misleading the user.

The really pernicious aliases show up as noise at the same frequencies as your data.  There's no way to tell what's real and what's not.  I'm sure it's caused more than one PID controller to intermittently fail in weird ways.

A spike in the ADC output caused by aliasing implies the presence of white noise from Nyquist to 2x Nyquist.
I'd expect (but have not done an analysis) that the sample & hold filters that to some degree.

An alpha trimmed mean is great for rejecting noise in many contexts, but rather difficult to analyze from a DSP perspective.  I've used it a lot, but all the data was guaranteed not to be aliased by the acquisition system.

--- On Wed, 10/10/12, Onestone wrote:

From: Onestone
Subject: Re: [msp430] Re: Glitches with ADC12 internal temperature sensor
To: m...
Date: Wednesday, October 10, 2012, 4:20 AM

 





perhaps that should be the next peripheral that Ti include. A

programmable cut off low pass filter. It would be an excellent, and

perhaps obvious peripheral for any device with an A/D, and something I

don't think anyone else does as a peripheral for a micro, although they

are available as stand alone parts.

Al

On 10/10/2012 12:00 AM, Reginald Beardsley wrote:

> If you've not actually calculated the filter response of averaging you should. There are several free MATLAB clones that will do this for you.

>

> And yes, eliminating microvolt level noise is hard, especially in an MCU design. Consider the requirements for the 24 bit delta-sigma version of the 430, -144dB at Nyquist. That's seriously hard to do. It's actually a strong argument for as many poles of analog filter as you can reliably build, followed by oversampled conversion and additional digital filtering and decimation.

>

> Have Fun!

> Reg

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>

>