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

NRF52832 physical pin analogRead

Hello,

I'm trying to read an ADC value from a sensor(for POC I'll be using a pot wired to 3.3V VDD and GND) but all the examples I found only demonstrated reading the internal VDD with the 0.6V reference:

for example(simplest code I found):

github.com/.../main.c

and nothing with the VDD reference and an actual physical pin....

does anybody has an idea were can you get such an example or at least how should the example code be modified to work with say pin "P0.04" sins I'm quite a noobie?

Thanks for your time.

  • Yeah I'm always learning with the info center and nrf_drv_saadc_channel_init is just initializing the channel in the IC internally and I'm looking to see how to hook it up to a pin, or maybe I got the Idea wrong and it's somehow proportional to the pin any how I couldn't find the function nrf_drv_saadc_channel_init in the example and the macro that has something to do with pins according to the infocenter"NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE"

  • Same as what was noted above by Matt, this is part of the channel configure. The definitions are part of the SAADC driver library and you will find them in any project that utilizes the SAADC. But here are the definitions for your reference:

    /**
     * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings
     *        in single ended mode.
     *
     * @param PIN_P Analog input.
     */
    #define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \
    {                                                      \
        .resistor_p = NRF_SAADC_RESISTOR_DISABLED,         \
        .resistor_n = NRF_SAADC_RESISTOR_DISABLED,         \
        .gain       = NRF_SAADC_GAIN1_6,                   \
        .reference  = NRF_SAADC_REFERENCE_INTERNAL,        \
        .acq_time   = NRF_SAADC_ACQTIME_10US,              \
        .mode       = NRF_SAADC_MODE_SINGLE_ENDED,         \
        .pin_p      = (nrf_saadc_input_t)(PIN_P),          \
        .pin_n      = NRF_SAADC_INPUT_DISABLED             \
    }
    
    /**
     * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings
     *        in differential mode.
     *
     * @param PIN_P Positive analog input.
     * @param PIN_N Negative analog input.
     */
    #define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(PIN_P, PIN_N) \
    {                                                                       \
        .resistor_p = NRF_SAADC_RESISTOR_DISABLED,                          \
        .resistor_n = NRF_SAADC_RESISTOR_DISABLED,                          \
        .gain       = NRF_SAADC_GAIN1_6,                                    \
        .reference  = NRF_SAADC_REFERENCE_INTERNAL,                         \
        .acq_time   = NRF_SAADC_ACQTIME_10US,                               \
        .mode       = NRF_SAADC_MODE_DIFFERENTIAL,                          \
        .pin_p      = (nrf_saadc_input_t)(PIN_P),                           \
        .pin_n      = (nrf_saadc_input_t)(PIN_N)                            \
    }
    

    Here is the same stuff in the API reference on the Nordic website: infocenter.nordicsemi.com/index.jsp

    If you need help in making sense of the code, in the below code I pulled the channel_config struct into the init so you can easily edit the config info. Also, it has been set to 0.4 and VDD/4 reference. This code was done in SDK12.2 but the saadc doesn't change much so you can probably use it in any SDK.

    #include "nrf_drv_saadc.h"
    
    #define SAMPLES_IN_BUFFER 1               //Number of SAADC samples in RAM before returning a SAADC event. 
    
    
    static nrf_saadc_value_t m_buffer_pool[2][SAMPLES_IN_BUFFER];
    
    void saadc_callback(nrf_drv_saadc_evt_t const * p_event) 
    	{ 
    		uint32_t pin_sample;
    
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        ret_code_t err_code;
        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    
        for (int i = 0; i < SAMPLES_IN_BUFFER; i++)
        {
                    pin_sample = p_event->data.done.p_buffer[i]>>2;
        }
    
    //At this point your pin level is captured in pin_sample. You can do whatever you want with it now
    
    nrf_drv_saadc_uninit(); //Turns off SAADC
        NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);
        NVIC_ClearPendingIRQ(SAADC_IRQn);
    
    }
    }
    
    void saadc_init(void)
    { 
    	ret_code_t err_code; 
    	
    //Just look up the options on the enumerations in the reference info, product spec or in nrf_drv_saadc.h
    	nrf_saadc_channel_config_t channel_config = {                                                  \
            .resistor_p = NRF_SAADC_RESISTOR_DISABLED,     \
            .resistor_n = NRF_SAADC_RESISTOR_DISABLED,     \
            .gain       = NRF_SAADC_GAIN1_6,               \
            .reference  = NRF_SAADC_REFERENCE_VDD4,    \
            .acq_time   = NRF_SAADC_ACQTIME_10US,          \
            .mode       = NRF_SAADC_MODE_SINGLE_ENDED,     \
            .burst      = NRF_SAADC_BURST_DISABLED,        \
            .pin_p      = NRF_SAADC_INPUT_AIN2,      \
            .pin_n      = NRF_SAADC_INPUT_DISABLED         \
        };
    	
    	err_code = nrf_drv_saadc_init(NULL, saadc_callback); 
    	APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_saadc_channel_init(0, &channel_config);
    APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0],SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1],SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
    
    }
    
    
    
    //Finally this is the function you would call to start a saadc sample session
    
    void start_saadc(void)
    
    { 
    saadc_init(); 
    nrf_drv_saadc_sample(); 
    }
    
  • Doesn't realy answers my question I'm trying to figure out how to edit one of the example codes to give me a voltage reading from say pin P0.03 and get the value into a buffer named say "VoltageBuffer"

  • after some more digging I understood(Kind of got reminded) that the channels can't be enforced to another pins and the correspond to this pinout: infocenter.nordicsemi.com/index.jsp

    But still doesn't solve the mystery of getting the wrong reading after debugging the example shorting it to ground NOR to VDD helps.

  • I doubt you can re-map the analog input pin; there are 4 or 6 of them, I could not remember... you need to consult with Nordic tech support on this one.

Related