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

how to use 3 channels of ADC in non blockin mode?

Hello all, am trying to configure 3 adc channels in a way to have conversion in 3 differents pins, without usin timer and ppi. so I implement the following code, the problem is that I have a static error in a channel which is supposed to be null, for example, when I set a tension in the pin A at 3.3V, I have a input tension of about 1.3V in the pin B, and when I sent a tension of 3.3V in the pin B, I have the static error in the pin C, and when I decrease the input tension, the static error decrease also. So, there is my code implemenation :

#include "adc.hpp"

#include "boardConfig.hpp"
#include "uart.hpp"
#include "app_error.h"

#define SAMPLES_IN_BUFFER 3

static nrf_saadc_value_t       buffer_adc[CHANNEL_NUMBER][SAMPLES_IN_BUFFER];
static int16_t adc_result;
static uint8_t adc_channel_enabled;

nrf_saadc_channel_config_t adc_channel_cfg_0 =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);

nrf_saadc_channel_config_t adc_channel_cfg_1 =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);

nrf_saadc_channel_config_t adc_channel_cfg_2 =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);

nrf_saadc_channel_config_t adc_channel_cfg_3 =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3);

nrf_saadc_channel_config_t adc_channel_cfg_4 =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);

nrf_saadc_channel_config_t adc_channel_cfg_5 =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5);

nrf_saadc_channel_config_t adc_channel_cfg_6 =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN6);

nrf_saadc_channel_config_t adc_channel_cfg_7 =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);

static void (*ptrFcnArray[CHANNEL_NUMBER])(int16_t) = {NULL};

void adcHandler(nrf_drv_saadc_evt_t const *p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);

        if(ptrFcnArray[0] != NULL && ptrFcnArray[1] != NULL)
        {
            if(adc_channel_enabled == 0)
            {
                nrf_drv_saadc_channel_uninit(1);
                nrf_drv_saadc_channel_uninit(2);
                nrf_drv_saadc_channel_init(0, &adc_channel_cfg_0);
                adc_channel_enabled = 1;
                nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
                adc_result = p_event->data.done.p_buffer[0];
                ptrFcnArray[0](adc_result); // Pointer of a function which handles the resule of ADC conversion in channel 0

            }

            else if(adc_channel_enabled == 1)
            {
                nrf_drv_saadc_channel_uninit(0);
                nrf_drv_saadc_channel_uninit(2);
                nrf_drv_saadc_channel_init(1, &adc_channel_cfg_1);
                adc_channel_enabled = 2;
                nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
                adc_result = p_event->data.done.p_buffer[1];
                ptrFcnArray[1](adc_result); // Pointer of a function which handles the resule of ADC conversion in channel 1
            }

            else if(adc_channel_enabled == 2)
            {
                nrf_drv_saadc_channel_uninit(0);
                nrf_drv_saadc_channel_uninit(1);
                nrf_drv_saadc_channel_init(1, &adc_channel_cfg_2);
                adc_channel_enabled = 0; 
                nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
                adc_result = p_event->data.done.p_buffer[2];
                ptrFcnArray[2](adc_result); // Pointer of a function which handles the resule of ADC conversion in channel 2
            }
        }
    }
}


int initADCModule()
{
    nrf_drv_saadc_config_t adc_cfg = NRF_DRV_SAADC_DEFAULT_CONFIG;
    nrf_drv_saadc_init(&adc_cfg, adcHandler);

    nrf_drv_saadc_channel_init(ADC_CHANNEL_0, &adc_channel_cfg_0);
    nrf_drv_saadc_channel_init(ADC_CHANNEL_1, &adc_channel_cfg_1);
    nrf_drv_saadc_channel_init(ADC_CHANNEL_2, &adc_channel_cfg_2);

    adc_channel_enabled = 0;

    nrf_drv_saadc_buffer_convert(buffer_adc[0], SAMPLES_IN_BUFFER);
    nrf_drv_saadc_buffer_convert(buffer_adc[1], SAMPLES_IN_BUFFER);
    nrf_drv_saadc_buffer_convert(buffer_adc[2], SAMPLES_IN_BUFFER);    
    return 0;
}

void uinitADCModule()
{
    nrf_drv_saadc_uninit();
}

void uinitADCChannel(uint8_t id_channel)
{
    nrf_drv_saadc_channel_uninit(id_channel);
}

int16_t getBlockinValue(uint8_t id_channel)
{
    nrf_saadc_value_t res_conv;
    nrf_drv_saadc_sample_convert(id_channel, &res_conv);
    return res_conv;
}

void startADC()
{
    nrf_drv_saadc_sample();
}

Can someone help me please?

Parents
  • I don't understand your code. First you initialize all 3 channels, then you use some flag to indicate which channel is enabled, then you setup three different buffers for conversion (only two buffers can be setup for conversion at a time), and then uninit two of he channels in the callback.

    You can use scan mode to sample all three channels at once. The samples will be stored in the buffer like this: [channel0,channel1,channel2,channel0,...]. You can find an example of how to use scan mode on our Github. This can easily be changed to call the nrf_drv_saadc_sample manually if you don't want to use timer/PPI.

    I also don't understand why you are sampling unconnected inputs. Are you getting wrong samples with inputs connected?

  • I don't understand your code. First you initialize all 3 channels, then you use some flag to indicate which channel is enabled, then you setup three different buffers for conversion (only two buffers can be setup for conversion at a time), and then uninit two of he channels in the callback. -> the idea is to have is to made conversion in only one channel in each interruption, now i resolve the problem to have conversion for all channels using p_event->data.done.p_buffer buffer.

    I also don't understand why you are sampling unconnected inputs. Are you getting wrong samples with inputs connected? -> Juste to be sure that nothing hapens in the non connected pins.

Reply
  • I don't understand your code. First you initialize all 3 channels, then you use some flag to indicate which channel is enabled, then you setup three different buffers for conversion (only two buffers can be setup for conversion at a time), and then uninit two of he channels in the callback. -> the idea is to have is to made conversion in only one channel in each interruption, now i resolve the problem to have conversion for all channels using p_event->data.done.p_buffer buffer.

    I also don't understand why you are sampling unconnected inputs. Are you getting wrong samples with inputs connected? -> Juste to be sure that nothing hapens in the non connected pins.

Children
No Data
Related