ADC output voltage

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ADC output voltage

Jump to solution
4,356 Views
tobias_mrs
Contributor III

Hello
I work with a MKE18F512 and I have to use the ADC.

We work with 5V Supply and a external 5V Ref
Now I have the problem that the any ADC pin is at 2,5V and delivers up to 20µA out current.

Could this be correct?
Why are the ADC pin at 2,5 in idle position.
To test this problem I have disconnect all connections form the ADC pin but it stays at 2,5V if the ADC run.

I am happy about any idea.
regards
Tobias

Labels (1)
0 Kudos
1 Solution
3,922 Views
tobias_mrs
Contributor III

Hello
now we have found a reason for our problems.
The security resistor for the ADC, with 10kOhm, is to big.
If we use a 100Ohm resistor we don't have this problems, the voltage drop is lower with the 100 Ohm resistor.

I have done a test with the demoboard and the potentiometer and better measurement units.

First I changed the example to use 12 bit ADC result and 16bit hardware average.

Then I replaced jumper J9 with a resistor. 
10kOhm:  ADC => Min 271 ... Max 3998

100Ohm: ADC=> Min 0 ... Max 4094

Jumper: ADC=> Min 0 ... Max 4094.

Thank you four your help.
Tobias Härter

View solution in original post

0 Kudos
12 Replies
3,922 Views
tobias_mrs
Contributor III

Hello
Now I have the demoboard on my desk.
I use the example twrke18f_adc12_interrupt and I have changed the AC to a 12 bit resolution.

At a normal run the console outputs
Poti max => ADC Value: 4094
Poti min => ADC Value: 0

The potentiometer is directly connected with the ADC input.
Now I have replaced the Jumper J9 with a 10kOhm resistor and now I could measure the wrong offset.

Poti max =>  ADC Value: 3798

Poti min => ADC Value: 54

What is wrong with this security resistor in front of the ADC input?
What is wrong a our ADC Schematic?

Regards
Tobias Härter

0 Kudos
3,923 Views
tobias_mrs
Contributor III

Hello
now we have found a reason for our problems.
The security resistor for the ADC, with 10kOhm, is to big.
If we use a 100Ohm resistor we don't have this problems, the voltage drop is lower with the 100 Ohm resistor.

I have done a test with the demoboard and the potentiometer and better measurement units.

First I changed the example to use 12 bit ADC result and 16bit hardware average.

Then I replaced jumper J9 with a resistor. 
10kOhm:  ADC => Min 271 ... Max 3998

100Ohm: ADC=> Min 0 ... Max 4094

Jumper: ADC=> Min 0 ... Max 4094.

Thank you four your help.
Tobias Härter

0 Kudos
3,922 Views
tobias_mrs
Contributor III

To give you a better overview about the situation I have attached the schematics of the ADC

For example if I remove R407 I measure 2.5V at X407 if the ADC runs and sample the input. That could not be OK.

0 Kudos
3,921 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Tobias,

 

I have tried this using the TWR-KE18F and the ADC example adc12_interrupt that is using the PTC14 as input that is connected to a potentiometer and checking the code I only could thing that the reg_port_gpio not have the correct muxing from the pins, also to check the correct pin functionality did you check if they can be used as GPIO or connected to one of the peripherals?

 

Let me know your findings.

 

Best Regards,

Alexis Andalon

0 Kudos
3,922 Views
tobias_mrs
Contributor III

Hello Alexis

I have checked the  reg_port_gpio, but it is correct, it point to the FSL define PORTA.

I have also checked:

- the usage as GPIO is OK.

- I used a second hardware => same result

- I changed to use only one ADC channel => same result 2,5V output voltage

- I remove all hardware connections form the ADC pin ( pin 79 without any connection ) => 3.0V output voltage

- I used the example twrke18f_adc12_interrupt and changed it to usage of my ADC

#define DEMO_ADC12_BASE ADC0
#define DEMO_ADC12_CLOCK_SOURCE kADC12_ClockSourceAlt0
#define DEMO_ADC12_IRQn ADC0_IRQn
#define DEMO_ADC12_IRQ_HANDLER_FUNC ADC0_IRQHandler

/* Channel 12 is PTC14 on the board. */
//#define DEMO_ADC12_USER_CHANNEL 12U
//#define DEMO_ADC12_CHANNEL_GROUP 0U
// MRS 7xCC
#define DEMO_ADC12_USER_CHANNEL 0U
#define DEMO_ADC12_CHANNEL_GROUP 0U

=> now I have  output voltage of 2V on ADC0_SE0 pin 79

It seems that that there is something on my hardware, but what? I'm out of ideas.

Regards
Tobias

0 Kudos
3,922 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello tobias_mrs‌,

Do you have a TWR board where you could replicate this issue with code your using? If this can't be replicated it could mean that something in the hardware is the problem. For reference you could check the schematics form the TWR-KE18 (check link here).

Let me know your findings.

Best Regards,

Alexis Andalon

0 Kudos
3,922 Views
tobias_mrs
Contributor III

Hello Alexis thank you four your help.

I have attached at schematic to clarify our problem.
Because of the output current of the ADC input, our measurement is falsified by several mV.
20200218_074529.jpg
Could you measure the voltages at the demoboard, e.g. PTA6/ADC0_SE2_ELEV at both sides of R147. With the potentiometer ADC input you don_t have access to the both voltages.

0 Kudos
3,922 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Tobias,

As you mention in the demoboard is also present this behavior, doing measurement in R147 I found voltages less than 7mV but using the potentiometer to take some measurements I found that this little voltage if the pin is drive externally doesn't affect the measurement, so I think the little drifting in your board could be due to other reason. I will suggest to check the following application notes:

How to Increase the Analog-to-Digital Converter Accuracy in an Application

Cookbook for SAR ADC Measurements

Understanding ADC specifications 

Best Regards,

Alexis Andalon

0 Kudos
3,922 Views
tobias_mrs
Contributor III

Hello Alexis
We have ordered a demoboard to do some measurements.
But this output voltage has a effect to the measurement! And this output voltage / this output current differs with the measurement voltage.
We have analyzed the documents, but there is at no point a output current.

We have also done a quick measurement with a Kinetis MK10DN512 and have not found the output voltage.

We will now wait for the demoboard to add there our measurement and test it. 
Best regards
Tobias Härter

0 Kudos
3,922 Views
tobias_mrs
Contributor III

We don't have a demoboard.
Now we have removed almost all external connections and the VREFF and use the example Software => Same result 2V at the running ADC pin. I have also done the the same test with the normally unused ADC2 at port D => same result 2V at pin 4.
We have also checked the schematics form the TWR-KE18.

Regards

Tobias

0 Kudos
3,922 Views
tobias_mrs
Contributor III

Hello
Yes I have attached my code.
I have also tested only the example code of the SDK and only initialize one ADC input but with the same result.

ADC12_GetDefaultConfig( &adc_config );
//    adc_config->referenceVoltageSource = kADC12_ReferenceVoltageSourceVref;
//    adc_config->clockSource = kADC12_ClockSourceAlt0;
//    adc_config->clockDivider = kADC12_ClockDivider1;
//    adc_config->resolution = kADC12_Resolution8Bit;
//    adc_config->sampleClockCount = 12U;
//    adc_config->enableContinuousConversion = false;
adc_config.resolution = kADC12_Resolution12Bit;

// go thru all ADC channels
for( used_io_pin = ANA_IN_START; used_io_pin < ANA_IN_MAX; used_io_pin++ )
{
    used_adc_pin = get_adc_io_number( used_io_pin );
    // enable clock and pinmux of port
    CLOCK_EnableClock( get_fsl_port_clock_name( ai_pin[used_adc_pin].port ) );

    // no pull resistor
    reg_port_gpio[ai_pin[used_adc_pin].port]->PCR[ai_pin[used_adc_pin].pin] = ( (reg_port_gpio[ai_pin[used_adc_pin].port]->PCR[ai_pin[used_adc_pin].pin]                                                                            & ( ~( PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_ISF_MASK ) ) )                                                                         | PORT_PCR_PS( 0 ) | PORT_PCR_PE( 0 ) );

    PORT_SetPinMux( reg_port_gpio[ai_pin[used_adc_pin].port], ai_pin[used_adc_pin].pin, kPORT_PinDisabledOrAnalog );

    // set clock source of ADC
    CLOCK_SetIpSrc( get_fsl_adc_clock_name( ai_pin[used_adc_pin].adc ), kCLOCK_IpSrcFircAsync );
    // enable interrupt
    EnableIRQ( get_fsl_adc_interrupt_name( ai_pin[used_adc_pin].adc ) );

    // enable all used ADC modules
    ADC12_Init( reg_adc[ai_pin[used_adc_pin].adc], &adc_config );
    ADC12_SetHardwareAverage( reg_adc[ai_pin[used_adc_pin].adc],  kADC12_HardwareAverageCount8 );
    // Set to software trigger mode.
    ADC12_EnableHardwareTrigger( reg_adc[ai_pin[used_adc_pin].adc], FALSE );

    ADC12_DoAutoCalibration( reg_adc[ai_pin[used_adc_pin].adc] );
}

// start ADC measurement at each ADC
for( a = (enum_adc_t) 0; a < ADC_MAX; ++a )
{
    for( c = 0; c < ANA_IN_CNT; ++c )
    {
        // search for first channel and start this
        if( ai_pin[c].adc == a )
        {
           mgl_adc_ctrl[a].ptr_actual_channel = &ai_pin[c]; // set channel

           // start measurement
           adc_channel_config.channelNumber = ai_pin[c].channel;
           adc_channel_config.enableInterruptOnConversionCompleted = TRUE;

           ADC12_SetChannelConfig( reg_adc[ai_pin[c].adc], 0, &adc_channel_config );
           break;
         }
         else
         {
            // check next
         }
    }// end loop ADC IO pins
} // end loop ADC‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

read ADC at interrup

void adc_process( enum_adc_t adc )
{
    adc12_channel_config_t adc_channel_config;

    // get value
    uint8_t channel = get_adc_io_number( mgl_adc_ctrl[adc].ptr_actual_channel->name );

    mgl_adc_values[ channel ].actual_ui16 = ADC12_GetChannelConversionValue( reg_adc[adc], 0 );

    //set next channel to indicate a single conversion
    switch_to_next_adc_channel( adc );

    adc_channel_config.channelNumber =  mgl_adc_ctrl[adc].ptr_actual_channel->channel;
    adc_channel_config.enableInterruptOnConversionCompleted = TRUE;
    ADC12_SetChannelConfig( reg_adc[adc] , 0, &adc_channel_config );

    __DSB(); // Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping exception return operation might vector to incorrect interrupt.
}

/*----------------------------------------------------------------------------*/
/**
 * Interrupt service routine (ISR) for ADC 0
 *
 * \internal
 * Call adc_process to get the value and start measurement of next channel.
 * \endinternal
 */
void ADC0_IRQHandler( void )
{
    adc_process( ADC_0 );
}


I get the result form the interrupt and switch there to the next channel.

0 Kudos
3,922 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Tobias,

This is a little weird since the ADC pins should be inputs, in the pin multiplexing did you enable the analog pin? You could check how to do this in the ADC SDK examples, in the BOARD_InitPins() that enable the analog function.

Best Regards,

Alexis Andalon

0 Kudos