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.

MSP432 - ADC value too low

Hi,

I just downloaded the MSP432F401R-ADC routine of the real time operating system and tried the ADC driver. I try to use examples and compile everything. However, the value ADC reads is lower than the actual value (from the multimeter).
The voltage is equal to 1.73V of the multimeter, and the ADC driver returns a tension of 1.0V (using the function ADC_convertRawToMicroVolts).


Here is the configuration of ADC:

  • Could you provide a complete .zip of the code you used or the full path to the example along with which IDE you are using so I can look into this?

    The example I would expect you to use for starters wold be the "adcsinglechannel" project, which can be found from within Resource Explorer.

    Regards,

     Bob

  •  Bob

    Here is my "adcsinglechannel.c" file source code, thank you very much!

    /* ADC conversion result variables */
    uint16_t adcValue0;
    uint32_t adcValue0MicroVolt;
    uint16_t adcValue1[ADC_SAMPLE_COUNT];
    double rc = 0;
    double rt = 0;
    double voltage = 0;
    /*
     *  ======== taskFxn0 ========
     *  Open an ADC instance and get a sampling result from a one-shot conversion.
     */
    Void taskFxn0(UArg arg0, UArg arg1)
    {
        int8_t i = 0;
        ADC_Handle adc;
        ADC_Params params;
        int_fast16_t res;
        GPIO_write(Board_ADC, 0);
        while (1)
        {
            double voltage1 = 0,voltage2 = 0;
            ADC_Params_init(&params);
            adc = ADC_open(Board_ADC0, &params);
            if (adc == NULL)
            {
                System_abort("Error initializing ADC channel 0\n");
            }
            else
            {
                System_printf("ADC channel 0 initialized\n");
            }
            Task_sleep(1000 * 1000 / Clock_tickPeriod);
            /* Blocking mode conversion */
            for (i = 0; i < 5; i++)
            {
                res = ADC_convert(adc, &adcValue0);
                adcValue0MicroVolt = ADC_convertRawToMicroVolts(adc, adcValue0);
                voltage = (double) adcValue0 * 2.5f / 16383.0f;
                voltage1 = voltage1 + voltage;
            }
            voltage2 = voltage1 / i;
            if (res == ADC_STATUS_SUCCESS)
            {
                System_printf("ADC channel 0 convert result: 0x%x\n", adcValue0);
            }
            else
            {
                System_printf("ADC channel 0 convert failed\n");
            }
            ADC_close(adc);
            Task_sleep(1000 * 1000 / Clock_tickPeriod);
        }
        System_flush();
    }
    /*
     *  ======== taskFxn1 ========
     *  Open a ADC handle and get a array of sampling results after
     *  calling several conversions.
     */
    Void taskFxn1(UArg arg0, UArg arg1)
    {
        uint16_t i;
        ADC_Handle adc;
        ADC_Params params;
        int_fast16_t res;
        ADC_Params_init(&params);
        adc = ADC_open(Board_ADC1, &params);
        if (adc == NULL)
        {
            System_abort("Error initializing ADC channel 1\n");
        }
        else
        {
            System_printf("ADC channel 1 initialized\n");
        }
        for (i = 0; i < ADC_SAMPLE_COUNT; i++)
        {
            res = ADC_convert(adc, &adcValue1[i]);
            if (res == ADC_STATUS_SUCCESS)
            {
                System_printf("ADC channel 1 convert result (%d): 0x%x\n", i,
                              adcValue1[i]);
            }
            else
            {
                System_printf("ADC channel 1 convert failed (%d)\n", i);
            }
            System_flush();
        }
        ADC_close(adc);
    }
    /*
     *  ======== main ========
     */
    int main(void)
    {
        Task_Params taskParams;
        /* Call board init functions */
        Board_initGeneral();
        Board_initADC();
        Board_initGPIO();
        /* Create tasks */
        Task_Params_init(&taskParams);
        taskParams.stackSize = TASKSTACKSIZE;
        taskParams.stack = &task0Stack;
        Task_construct(&task0Struct, (Task_FuncPtr) taskFxn0, &taskParams, NULL);
        Task_Params_init(&taskParams);
        taskParams.stackSize = TASKSTACKSIZE;
        taskParams.stack = &task1Stack;
        Task_construct(&task1Struct, (Task_FuncPtr) taskFxn1, &taskParams, NULL);
        System_printf(
                "Starting the ADC Single Channel example\nSystem provider is "
                "set to SysMin.  Halt the target to view any SysMin contents in ROV.\n");
        /* SysMin will only print to the console when you call flush or exit */
        System_flush();
        BIOS_start();
        return (0);
    }

  • Bob

    The following is my principle, I connected the two resistors, the input voltage of the divider, the present situation is that the voltage input is connected to my 4V, tens of thousands of voltage meter reads the value of 1.6V, the universal voltage meter read value is 0.8V.

  • If I understand you correctly, your meter is reading 0.8v and the software is reporting 1.6v.

    Assuming that output on P5.7 is low and assuming typical 5-10% tolerances on the resistors, the 1.6v value seems reasonable.

    I do notice somethign strange in the code above in the first while() loop. Namely, you seem to be double-converting the  ADC result:

                res = ADC_convert(adc, &adcValue0);
                adcValue0MicroVolt = ADC_convertRawToMicroVolts(adc, adcValue0);
                voltage = (double) adcValue0 * 2.5f / 16383.0f;
                voltage1 = voltage1 + voltage;
    The function ADC_convertRawToMicroVolts() takes the input and ALREADY converts it to a volts value. From there you don't need the highlighted line which would normally be used to convert a binary value to an actual volts value (here, for a 2.5v reference and 14-bit ADC read).
    Can you confirm what are reading at each step in this sequence? (namely:
    1. what is the value of adcValue0 at each read?
    2. What is the voltage present on P5.7 ? or is this configured as an input?
    3. Is it your meter that is reading 0.8v on P5.5?

**Attention** This is a public forum