This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430G2553 ADC Sampling Accuracy

Other Parts Discussed in Thread: MSP430G2553, INA196

Hi, 

I am using the MSP430G2553 and would like to sample values using the ADC10 at 80 Hz. Currently, I am converting the samples in my main loop (it runs at approximately 12.9 kHz) and wait until the conversion is done before moving on to execute the rest of the main loop. Vss and 2.5Vref are used as references. Using an interrupt, I save the converted values at 80 Hz. The relevant ADC code is attached.

To see if the ADC is working I input a constant signal and store 200 int values of the digital signal after sampling and view them in the CCS debugger. I am seeing some slight noise in my signal, up to 8 quantization levels (or up to 19.5 mV). Attached is a plot of the 200 values stored after ADC. When looking at the input signal using a Labview DAQ, there is baseline noise of only 6 mV as opposed to 19.5 mV seen in the digital signal.

 I am wondering if the noise present in my digital signal is likely caused by the conversion and saving of ADC values. If yes, am I using ADC10 correctly to save my samples? Or is there a better method to sample at a specified frequency? 

Thanks!

Tyler

3201.ADC code.txt
#include "msp430g2553.h"
#include <in430.h>
#include "main.h"

static const int timer_A = 1600;
int testdata[200];
volatile unsigned int update = 0; //incremented with adc
volatile unsigned int updatetd = 0;

int main( void )
{
	WDTCTL = WDTPW + WDTHOLD;
	setupGPIO(); //setup the pins
	setupTimer_A(); //setup timer A
	setupADC(); //setup the ADC
	TA0CTL |= MC_1;
	__enable_interrupt(); //enable interrupts

	while(1)
	{
		ADC10CTL0 |= ENC + ADC10SC; //enable and start conversion of ADC samples
		while((ADC10CTL1 & ADC10BUSY));	//wait until conversion is done
		if(update > 0) {
			//////Toggle pin to determine ADC rate
			P2OUT ^= BIT0;
			update = 0; //turn off update
			}
		}
}
//----------------------INTERRUPTS----------------------

//Timer A interrupt for saving adc values(80 Hz)
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A( void )
{
	update= 1;//turn on update
	testdata[updatetd]=ADC10MEM;
	updatetd++;
}

//----------------------FUNCTIONS----------------------
void setupGPIO( void )
{

	//Pins for checking rates
	//P2.0 for length of main loop
	P2SEL &= ~BIT0;
	P2DIR |= BIT0;
	P2OUT &= ~BIT0; //turn off
}

//Timer A is for saving adc values at 80 Hz
void setupTimer_A( void )
{
	TA0CTL = TASSEL_2 + ID_3 + MC_0 + TACLR; //source from SMCLK, divide by 8, keep the timer off initially, clear the timer
	TA0CCTL0 = CCIE; //capture/compare interrupt enabled
	TA0CCR0 = timer_A; //Timer A to trigger at 80 Hz
}
//ADC is for sampling P1.1
void setupADC( void )
{
	ADC10CTL0 = ADC10SHT_3 + SREF_1 + REF2_5V + REFON + ADC10ON;
	ADC10CTL1 = INCH_1;
	ADC10AE0 |= BIT1;
	P1SEL |= BIT1;
}



  • Tyler Young said:

     I am wondering if the noise present in my digital signal is likely caused by the conversion and saving of ADC values. If yes, am I using ADC10 correctly to save my samples? Or is there a better method to sample at a specified frequency? 

     If you need 80Hz sampling it is a bad idea to do 12.5KHz samplig then discard a lot of convertion values. Different if you wish to do digital filtering smoothing signal. Start convertion by timer or software and trigger @80Hz you need.

     Are sampling and hold set at appropriate value?

     Is input impedance of pin reading voltage low enough to not pick up noise or be influenced by internal swithec capacitor equivalent impedance?

     Analod VDD is clean enough  and properly filtered out?

  • Hi Roberto,

    Thanks for the response! I am planning on smoothing the values collected in the 80 Hz interrupt using a moving average of 4 points, so the final frequency would be 80/4 = 20 Hz. Is it OK to keep the conversion in the 12.5kHz loop or should I put the conversion in the interrupt as well?

    For the sampling and hold I have the value set to wait 64 cycles which looks like the maximum number of cycles for the SHT register.

    I have not checked the input impedance of the signal to see if it is low enough. How low does it need to be to avoid picking up noise or be influenced by the internal switch capacitor equivalent impedance? Can you explain this more?

    A computer is powering the microcontroller via the launchpad micro usb and I am not doing any filtering on it.

    Thanks!

    Tyler

  • Hi, just remark

    I've got the similar ADC result scattering for MSP430G25553 working on Launchpad and on another battery powered HW board. I use 12 Hz sampling rate with LPM3 during ADC sampling (internal ADC clock, Vref = Vdd). 

    BR

  • Hello Tyler,

    I would like to reiterate what Roberto said with regard to input impedance. The DAQ is likely using a buffer amplifier, either a low noise op amp or an instrumentation amplifier, before the A/D.  You didn't say that you had a buffer between your signal and the input A/D pin but, if not, you may want to try putting a decent op amp in front the A/D.  The low output impedance of the op amp will mitigate the interplay between your source signal and the A/D. 

    Low noise in the power supply doesn't hurt either and perhaps trying to power from batteries might provide another data point in your noise investigation.

  • The G2553 only has a combined supply input. That means that the ADC has the same supply voltage rail as the digital part. And any current ripple (such as caused by a running CPU) will generate noise on the analog supply and influence the conversion results.
    For this reason, even an absolutely clean input signal would usually cause noise in the LSBs, especially when VCC is used as reference, but also when the internal 1.5 or 2.5V reference are used. (since the return current causes voltage ripples on GND too, this directly influences the reference voltage, compared to any external reference GND level)

    However, your results look quite good for the G2553. Your planned averaging will flatten most of the noise.

     And yes, 64 ADC10CLK cycles are the maximum for the ADC10 in 2x family. On 5x family, it offers up to 1024 clock cycles, and there you can also use a timer to control the sampling time (rising PWM edge = start sampling, falling edge = stop sampling and start the conversion)

  • Jens-Michael Gross said:
    The G2553 only has a combined supply input. That means that the ADC has the same supply voltage rail as the digital part. And any current ripple (such as caused by a running CPU) will generate noise on the analog supply and influence the conversion results.

     Hi Jens, I later realized on launchpad pin are limited and separated analog power is just on DFN I am using in my application.

     Quantization noise is ok +- 1LSB, so on long track and impedance of board jumpers a lot of noise may be picked up and routed to processor.

     A good idea can be to place a capacitor just under socket pin 1 and 20 to reduce noise and see if spikes go away. Another source can be internal sampling, this can be lowered by a low pass filter, just try a 22 Ohm in series to voltage source and analog input pin and a capacitor between this input and ground pin as short as possible.

     On my application analog pin are unfiltered direct driven by an opamp (INA196) sensing the current so the only noise source was limited by ground plane separation from power pwm and analog. Analog power is separate and filtered from digital one.

    Digital mobile averaging 8 stage is applied before using the result from adc, ADC sample @12KHz two channel so torque loop is feed @750Hz and on this application motor pole cancel all quantization noise also when suddenly stop.

     Before to decide what action to do a better knowledge of application is a must, so what is the goal of application?

**Attention** This is a public forum