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.

MSP430FR2111: Unstable ADC readout when using driverlib

Part Number: MSP430FR2111

Hi,

I'm running a project on the following configuration: MSP430FR2111, driverlib 2.80.0.01, CCS 8.1.0.00011, optimization level 4 in favor of size

I initialize the ADC :

ADC_setupSamplingTimer(ADC_BASE, ADC_CYCLEHOLD_1024_CYCLES, ADC_MULTIPLESAMPLESENABLE);

And I sample some pretty stable voltage every 1 Sec - I get pretty stable readout ~540 ADC counts.

As the voltage is pretty stable and output impedance is low (decoupling capacitor), I'vet tried to reduce sample&hold time 

Now, When I initialize with the sampling timer with any value other than  ADC_CYCLEHOLD_512_CYCLES (even down to 4 cycles) I get approximately the same readout (~540)

BUT when I initialize it with ADC_CYCLEHOLD_512_CYCLES I receive an alternating readout: 415 - 670 - 415 -670 which on average is ~540 (the steady value)

As I have very limited code memory, I must use the highest optimization level which makes it a pain to debug. The basic flow is as follows:

  • Every 1 sec -
    • Configure ADC to sample channel 2: ADC_configureMemory(ADC_BASE, ADCINCH_2, ADC_VREFPOS_INT, ADC_VREFNEG_AVSS);
    • Start single channel repeated conversion (channel 2): ADC_startConversion(ADC_BASE, ADC_REPEATED_SINGLECHANNEL);
  • Within the ISR - 
    • I sum up ADC readout to a global array  <<< This one I inspect in Memory view
    • I do the summation for 4 times and then disable conversion ADC_disableConversions(ADC_BASE, true);
    • I averaging the 4 samples sum and get an averaged readout on which I act
    • If sampled channel == ADCINCH_2
      • Configure ADC to sample channel 1: ADC_configureMemory(ADC_BASE, ADCINCH_1, ADC_VREFPOS_INT, ADC_VREFNEG_AVSS);
      • Start single channel repeated conversion (channel 1): ADC_startConversion(ADC_BASE, ADC_REPEATED_SINGLECHANNEL);
  • Repeat after 1 sec


What can be the cause of this super-awkward behavior? Is it an optimization issue? Why only for ADC_CYCLEHOLD_512_CYCLES ???

Any direction would be appreciated.

Thanks

#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR (void)
{
	static uint8_t avgCycle = AVG_FACTOR;  // 4
	uint8_t source;

	switch (__even_in_range(ADCIV,12)){
        case  0: break; 	//No interrupt
        case  2: break; 	//conversion result overflow
        case  4: break; 	//conversion time overflow
        case  6: break; 	//ADCHI
        case  8: break; 	//ADCLO
        case 10: break; 	//ADCIN
        case 12:        	//ADCIFG0

            //Automatically clears ADCIFG0 by reading memory buffer
			source = ADCMCTL0 & ADCINCH;
			Measurement[source] += ADC_getResults(ADC_BASE);   // Gloabl. Inspected in Memory window
			avgCycle--;

			if(avgCycle == 0) {	// avgCycle == 0 && source==0. End of sampling sequence
				ADC_disableInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
				ADC_disableConversions(ADC_BASE, true);
				avgCycle = AVG_FACTOR;
				Measurement[source] /= AVG_FACTOR;
                                // ......

				if(source == ADCINCH_2) {
				   ADC_configureMemory(ADC_BASE, ADCINCH_1, ADC_VREFPOS_INT, ADC_VREFNEG_AVSS);
				    ADC_enableInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);
				    ADC_startConversion(ADC_BASE, ADC_REPEATED_SINGLECHANNEL);
			       }
			} // if avgCycle == 0
		break;	// case 12
        } // switch __even_in_range()
	LPM3_EXIT;	// inside ISR exit LPM3
}

  • Hi Eyalasko,

    Interesting finding, let's dig into this a bit. You mention that you tried the other sample and hold times, all the way down to 4 ADC clocks. Did you also try the settings larger than 512 (768 and 1024)? Are these results always stable? I would not expect the S/H timing to have significant impact on the conversion result once you get past the short time, seeing as you are measuring a DC signal. I'll give the DriverLib source a look to check the bits which are being cleared and set.

    Regards,
    Walter
  • Hey Walter,

    Thanks for your prompt response.

    I might have skipped some vals but I've checked at least 1024, 768, 512 (problematic), 256, 64, 16, 4. All, but 512, give same readout (as inspected in the global array Measurement[2] in memory view)
    The strange thing is that I do 4 samples averaging (for each of the channels: 2 & 1) and still I see consistent AVERAGED result of 415-670-415-670 on channel 2 (global var Measurement[2] in memory view).
    I can't tell if channel 1 results behave the same as its voltage is not that stable...

    Thansk again.
  • Calling ADC_disableConversions with (preempt=true) sets CONSEQ=0 and then ENC=0. This will stop a current conversion, but if it had already finished the IFG0 might still be set. (Or maybe even if it hadn't finished -- User Guide SLAU445H sec 21.2.7.6 helpfully says "results are unpredictable".) I've never tried it, so I don't know. All the same, I suggest you add:

    > ADC_clearInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);

    before the enableInterrupt call.
  • Hi Eyalasko,

    I am now suspecting that the issue you are having is related to a specific timing scenario that affects the way the ISR executes the sequence of conversions when 512 is selected as the cycle count.

    Before we discuss that, I did run some tests on my side as well using a similar hardware configuration (see below).  In my case I had a weak voltage divider setting 1/2 VCC as the ADC input voltage voltage, and I was referenced to AVCC/AVSS.  As such, I expected some noise in the measurements- but I wanted to see what the consistency looked like across different sampling windows.

    I did not see any major differences in the results between the different sampling windows.

    Looking more closely at your erroneous samples, I find something interesting mathematically.  You mention that when the issue occurs, your result is around 415 or 670.  Interestingly, if you take a /4 average of a typical value of 540, a value of 405 should result if you only integrated 3 samples but divided by 4.  Likewise, a value of 675 would be expected if you integrated 5 values but divided by 4.  Your application also seems to show this as alternating (415/670/415/670).  To me, this strongly suggests an ISR timing issue where somehow you only integrate x3 samples in one case and then x5 samples in the next case (x3, x5, x3, x5, x3), as opposed to x4, x4, x4, x4, x4 consistently over time.  This really makes me think that this is a digital / firmware / sequencing issue rather than an analog measurement issue.  One way to quickly check this would be to disable your averaging algorithm and run conversions with the 512 pulse and log them, and see if the issue goes away.

    I'll dig into your ISR sequencing to see if there is a specific order of operations that could be causing this.  The 512-cycle setting might just be making a specific timing scenario happen that breaks the logic as it is currently laid out.

    Regards,
    Walter

  • HI Walter, 

    thanks for your thorough follow-up.

    I'm afraid that reproducing the problem is a bit tricky. It indeed looks like a very subtle timing issue that occurs inconsistently.

    On the other day when I originally posted the question, this was happening consistently.

    Later trials did not show the phenomena, I'll re-try to reproduce it and then diasble the averaging as you suggested.

    Thanks again.

  • Understood, Eyalasko. I'll close this thread for now. Feel free to reply or post again and reference this thread for further discussion.

    Regards,
    Walter

**Attention** This is a public forum