4 years, 6 months ago.

ADC Read Problem

I connected the ADC pin 0 to the output of the light sensor and ran the following code. But the ADC values dont respond to the voltage on the LIGHT_SENSE output or any other analog signal. Any clues what the problem might be?

AnalogIn adc0(PD0);         // ADC Channel 0    
Serial PC(USBTX, USBRX);
DigitalOut LESDrive(PD6);   // Light Sensor Excitation

int main() {
    LESDrive.write(1); // Turn on Light Sensor.
    while(1)
    {
        pc.printf("ADC0=%d\n", adc0.read_u16());
        wait(1.0);    
    }
}

Verified with a multimeter that the LIGHT_SENSE signal is changing between 0-3 volts. But I'm getting flat 0 Output:

ADC0=0
ADC0=0
ADC0=0
ADC0=0

I would appreciate any help! Thank you.

Question relating to:

Silicon Labs' EFM32™ Wonder Gecko ARM® Cortex®-M4 based 32-bit microcontrollers (MCUs) provide flash memory configurations up to 256 kB, 32 kB of RAM and CPU speeds up to 48 MHz, ...
Comment on this question

1 Answer

4 years, 5 months ago.

Hi,

Turns out our API's don't properly enable the clocks for the peripheral yet.

I added

analogin_api.c

CMU_ClockEnable(cmuClock_ADC0, true);

to analogin_init(analogin_t *obj, PinName pin) in analogin_api.c and now it at least gives me some output:) Cannot verify if it's the correct output.

By the way, the quickest way to debug these problems is to export the project to Simplicity studio like this. Also it is much easier to debug when using mbed-src instead of mbed.

Please send a pull request with a fix if adc init does enable clocks.

posted by Martin Kojtal 18 May 2015

Will do once I verify the fix.

posted by Steven Cooreman 19 May 2015

I finally got the ADC working. The ADC handle was not being initialized so I initialized it as shown in the included code. I'm not sure if that's the most elegant way to do it (since ADC0 is hard coded) but it worked for me.

void analogin_init(analogin_t *obj, PinName pin)
{
 
	// Initialize ADC handle to ADC base address
	obj->adc = ADC0;

	/* Init with default settings */
	ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
	ADC_Init(obj->adc, &init);

	ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;

	/* Init for single conversion use, measure input channel with Vdd reference. */
	singleInit.reference = adcRefVDD;
	singleInit.resolution = adcRes12Bit;
	singleInit.acqTime = adcAcqTime32;
	singleInit.input =  adcSingleInpCh0;

	ADC_InitSingle(obj->adc, &singleInit);

	CMU_ClockEnable(cmuClock_ADC0, true);

	/* Init pins */
	analogin_preinit(obj, pin);
}

posted by Labi Shrestha 19 May 2015