This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How calibration SAADC Negative Value

hello Dev Zone.

i need help.

now i'm try to make IR Line-tracer and detector

how ever, when my detecting object far then range,

"saadc" value change to Negative

I asume that it will goto 0, but change to "-" Velue
please check my code and help me

int NRF52Pin::initialiseSAADC()
{
    static bool isConfig = false;

    if(!isConfig)
    {
        isConfig = true;
        
        // Configure the SAADC resolution.
        NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_12bit << SAADC_RESOLUTION_VAL_Pos;

        // No automatic sampling, will trigger with TASKS_SAMPLE.
        NRF_SAADC->SAMPLERATE = SAADC_SAMPLERATE_MODE_Task << SAADC_SAMPLERATE_MODE_Pos;

        // Enable SAADC (would capture analog pins if they were used in CH[0].PSELP)
        NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos;
       
        // Calibrate the SAADC (only needs to be done once in a while)
        NRF_SAADC->TASKS_CALIBRATEOFFSET = 1;
        while (NRF_SAADC->EVENTS_CALIBRATEDONE == 0);
        NRF_SAADC->EVENTS_CALIBRATEDONE = 0;
        while (NRF_SAADC->STATUS == (SAADC_STATUS_STATUS_Busy <<SAADC_STATUS_STATUS_Pos));
    }
    // Configure result to be put in RAM at the location of "result" variable.
    NRF_SAADC->RESULT.MAXCNT = 1;
    // adcSample -> int16_t adcSample
    NRF_SAADC->RESULT.PTR = (uint32_t)&adcSample;
    
    return DEVICE_OK;
}

    ...
    ...
    // no existing channel found
    if (channel == -1) return DEVICE_NOT_SUPPORTED;
    else
    {
        initialiseSAADC();
    }

    // Configure the SAADC channel with VDD as positive input, no negative input(single ended).
    NRF_SAADC->CH[0].PSELP = ((unsigned long)channel) << SAADC_CH_PSELP_PSELP_Pos;
    NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;
    
    // Start the SAADC and wait for the started event.
    NRF_SAADC->TASKS_START = 1;
    while (NRF_SAADC->EVENTS_STARTED == 0);
    NRF_SAADC->EVENTS_STARTED = 0;

    // Do a SAADC sample, will put the result in the configured RAM buffer.
    NRF_SAADC->TASKS_SAMPLE = 1;
    while (NRF_SAADC->EVENTS_END == 0);
    NRF_SAADC->EVENTS_END = 0;

    return adcSample;
}
...
...

Thanks,

Best Regards

Empe.

Parents Reply Children
  • Hello, Håkon

    Thanks for help.

    I need to adjust the Gain and Resolution values well.

    I also checked the contents of the link you wrote down.

    It helped a lot.

    by the way, I am using all 7 SAADC, At this time

    The current method uses only CH [0] to sample one pin ADC per 1 START trigger.

    The time division method is being used.

    Could this be a problem? Now i'm using "Case 1" Format

    do i need to change to "Case 2" Format?

    // Case 1
    // Init Part
    // Channel Value Change 1 to 7 
    Init_SAADC
    {
        ...
        ...
        NRF_SAADC->CH[0].PSELP = ((unsigned long)channel) << SAADC_CH_PSELP_PSELP_Pos;
        NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;
        ...
        NRF_SAADC->TASKS_START = 1;
        while (NRF_SAADC->EVENTS_STARTED == 0);
        NRF_SAADC->EVENTS_STARTED = 0;
    
        // Do a SAADC sample, will put the result in the configured RAM buffer.
        NRF_SAADC->TASKS_SAMPLE = 1;
        while (NRF_SAADC->EVENTS_END == 0);
        NRF_SAADC->EVENTS_END = 0;
    
        return adcSample;
    }
    
    
    // Case 2
    // Init Part
    Init_SAADC
    {
        ...
        ...
        NRF_SAADC->CH[channel].PSELP = ((unsigned long)channel#1) << SAADC_CH_PSELP_PSELP_Pos;
        NRF_SAADC->CH[channel].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;
        ...
        ...
    }

    Best Regards,

    Empe.

  • Hi Empe,

     

    Empe said:

    by the way, I am using all 7 SAADC, At this time

    The current method uses only CH [0] to sample one pin ADC per 1 START trigger.

    It shouldn't matter wrt. the result on a specific pin, if you time-mux the sampling, or if you let the SAADC sample each input for you. SAADC will do time-multiplexing when several inputs are selected.

     

    What value are you sampling? It is to be expected that you can get a negative number from the SAADC.

     

    Kind regards,

    Håkon

  • Hello, Håkon

    i'm try to sampling IR Receive value,

    minimum 130mv to max 3.05V

    so i was changed the setting Gain 1/4, Ref VDD/4, 14Bit resolution.

    What value are you sampling? It is to be expected that you can get a negative number from the SAADC.

    yes, I modified it according to your advice, my saadc looks like more stable,

    but as you say still negative input value is looking.

    Best Regards,

    Empe.

Related