ADC XMC4500 - Result is not usable

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hey Guys,

I have a question regarding the ADC App of DAVE 4 and hope that you can help me.
My project target is to read out the analog input value of a Poti and switch on or switch off the LED depending on the analoge value. A XMC4500 Relax Kit is used to get the desired results. I was guided by the ADC_MEASUREMENT_EXAMPLE_XMC45.
The outcoming result of the adc is saved into a variable "result_potentiometer". I am able to see the value of the variable by adding it to the expressions view after debugging. So there is a change of the value when I adjust the poti.

Now the problem is that I can not use this variable to switch on or off the LED because the value is always 0.

For Example:

if (result_potentiometer < 6)
{
DIGITAL_IO_SetOutputHigh(&LED_2);
}

The LED will never light up, although the value is something like 1000 (Expression View).

Felix

My Code:

int result_potentiometer;

int main(void)
{
DAVE_STATUS_t status;
status = DAVE_Init(); /* Initialization of DAVE Apps */
if(status == DAVE_STATUS_FAILURE)
{
/* Placeholder for error handler code. The while loop below can be replaced with an user error handler */
XMC_DEBUG(("DAVE Apps initialization failed with status %d\n", status));
while(1U)
{
}
}

/* Placeholder for user application code. The while loop below can be replaced with user application code. */
ADC_MEASUREMENT_StartConversion(&ADC_MEASUREMENT_0);
while(1U)
{
if (result_potentiometer > 1000)
{
DIGITAL_IO_SetOutputHigh(&LED_2);
}

else
{
DIGITAL_IO_SetOutputLow(&LED_2);
}
}

return 1;
}

/*End of measurements interrupt*/
void Adc_Measurement_Handler(void)
{
//Read out conversion results
result_potentiometer = ADC_MEASUREMENT_GetResult(&ADC_MEASUREMENT_Potentiometer_handle);

/*Re-trigger conversion sequence*/
ADC_MEASUREMENT_StartConversion(&ADC_MEASUREMENT_0);
}
0 Likes
7 Replies
User10215
Level 4
Level 4
First like received
Hi Felix,

where do you Switch the LED off? I only see the function "DIGITAL_IO_SetOutputHigh" that is manipulating the pin. If you want to Switch the LED off you'd additionaly have to have the function "DIGITAL_IO_SetOutputLow" somewhere.
Then you say "Now the problem is that I can not use this variable to switch on or off the LED because the value is always 0.". And a few sentences later "the value is something like 1000". That's pretty confusing!
If your value is around 1000 then of course nothing is going to happen to the LED because in your if-statement you are checking for a value SMALLER than 6 in order to switch on the LED!

Also the value 6 in your if-statement is pretty small as a threshold since you'll have some noise which might give you values bigger than 6 even when your Poti is turned all the way down.

Regards,
Niclas
0 Likes
Not applicable
Hey Niclas,

thanks for your reply. You are completely right. If I read my post it is also confusing for me 😄

First, I forgot about the function "DIGITAL_IO_SetOutputLow". I inserted it into the code and I changed the value 6 in the if-statement to a more meaningful value 1000. (modified code above)
In detail if result_potentiometer is larger than 1000 the LED should switch on, otherwise it should switch off.

An example to describe my problem with the 0: The potentiometer is adjusted in that way that the value of result_potentiometer = 400. The value is not larger than 1000 so the LED is off. Now I change the adjustment of the Poti that the outcoming value of the ADC is 1500. It is stored to result_potentiometer and the LED should switch on because the value is larger than 1000.
But the LED does not change. So I tried different combinations of the if statement and determined that it just makes sense if the variable result_potentiometer is always 0 although I see a different value in the expression view.

Furthermore when I use the code "if (result_potentiometer ==0) {..." the statement is always! true and the LED does not flicker.

I hope you can help me 😃
0 Likes
User10215
Level 4
Level 4
First like received
Hi Felix,

what value do you get when you turn the Poti all the way down? And what value do you get when you turn the Poti all the way up?
0 Likes
Not applicable
Niclas wrote:
Hi Felix,

what value do you get when you turn the Poti all the way down? And what value do you get when you turn the Poti all the way up?


The minimum value is 0 until 4 and the maximum value is 4095.
0 Likes
User10215
Level 4
Level 4
First like received
Can you set breakpoints in the rows with the functions with which you switch the LED on and off? I wanna see if the program gets there...specifically to the function where you switch on the LED. If not then you might have a problem with the interrupt, i.e. the ADC measures pretty fast (several hundret nanoseconds). So the CPU might only be serving the interrupt and never gets into the while-loop of the main-function.
Also can you please double-check that you have the correct pin for the LED? On the XMC4500 pin P1.0 and P1.1 are connected to LEDs.
0 Likes
Not applicable
Niclas wrote:
Can you set breakpoints in the rows with the functions with which you switch the LED on and off? I wanna see if the program gets there...specifically to the function where you switch on the LED. If not then you might have a problem with the interrupt, i.e. the ADC measures pretty fast (several hundret nanoseconds). So the CPU might only be serving the interrupt and never gets into the while-loop of the main-function.
Also can you please double-check that you have the correct pin for the LED? On the XMC4500 pin P1.0 and P1.1 are connected to LEDs.


Hey Niclas,

Thank you very much for your help. I guess you are right. There was a problem with the interrupt. I made small changes of the code (alteration of the type of result_potentiometer and switching of the code from while loop to if-condition) and now it works but I really dont know why.


XMC_VADC_RESULT_SIZE_t result_potentiometer;

int main(void)
{
DAVE_STATUS_t status;
status = DAVE_Init(); /* Initialization of DAVE Apps */
if(status == DAVE_STATUS_FAILURE)
{
/* Placeholder for error handler code. The while loop below can be replaced with an user error handler */
XMC_DEBUG(("DAVE Apps initialization failed with status %d\n", status));
while(1U)
{
}
}

ADC_MEASUREMENT_StartConversion(&ADC_MEASUREMENT_0);
while(1U);
return 1;

/*End of measurements interrupt*/
void Adc_Measurement_Handler(void)
{
//Read out conversion results
result_potentiometer = ADC_MEASUREMENT_GetResult(&ADC_MEASUREMENT_Potentiometer_handle);

if (result_potentiometer > 1000)
{
DIGITAL_IO_SetOutputHigh(&LED_2);
}
else
{
DIGITAL_IO_SetOutputLow(&LED_2);
}
}
0 Likes
User10215
Level 4
Level 4
First like received
Hi Felix,

as mentioned above the ADC-peripheral is very fast.DAVE actually tells you how fast a measurement is (see the field "Total conversion time" in the APP-configuration). You will see that once you trigger a conversion, with the default configuration of the APP, it will be done after 550 nanoseconds!
When you calculate a little bit you will also see that in these 550 nanoseconds the XMC4500-CPU can "only" do 66 clock cycles. So what happened to you is that after the CPU is done with your interrupt-routine the next measurement is already finished and the interrupt is pending. After exiting the interrupt it directly reenters the interrupt. The CPU simply has no time to return to the while loop!

By the way, you can switch off the interrupt and try this code:


XMC_VADC_RESULT_SIZE_t result_potentiometer;

int main(void)
{
DAVE_STATUS_t status;
status = DAVE_Init(); /* Initialization of DAVE Apps */
if(status == DAVE_STATUS_FAILURE)
{
/* Placeholder for error handler code. The while loop below can be replaced with an user error handler */
XMC_DEBUG(("DAVE Apps initialization failed with status %d\n", status));
while(1U)
{
}
}

/* Placeholder for user application code. The while loop below can be replaced with user application code. */
ADC_MEASUREMENT_StartConversion(&ADC_MEASUREMENT_0);
while(1U)
{
if (result_potentiometer > 1000)
{
DIGITAL_IO_SetOutputHigh(&LED_2);
}
else
{
DIGITAL_IO_SetOutputLow(&LED_2);
}

//Read out conversion results
result_potentiometer = ADC_MEASUREMENT_GetResult(&ADC_MEASUREMENT_Potentiometer_handle);
}

return 1;
}


Now the CPU also can do other stuff in the while-loop.

Regards,
Niclas
0 Likes