<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>How to read two analog inputs using SAADC?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/47600/how-to-read-two-analog-inputs-using-saadc</link><description>I have developed an application that reads data from an analog sensor and transmits data with UART. This app is based off the SDK v14.x uart example, and SAADC example. While my application works fine for reading one analog input, I now need to read data</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 19 Aug 2019 06:39:47 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/47600/how-to-read-two-analog-inputs-using-saadc" /><item><title>RE: How to read two analog inputs using SAADC?</title><link>https://devzone.nordicsemi.com/thread/204632?ContentTypeID=1</link><pubDate>Mon, 19 Aug 2019 06:39:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b21fbfa8-ce7c-46f3-8ab4-486ad85519b6</guid><dc:creator>paul_tanner</dc:creator><description>&lt;p&gt;I&amp;#39;m using sdk 12.3 on nrf52832.&amp;nbsp; I have a single&amp;nbsp; channel working fine and am extending it to two channels.&lt;/p&gt;
&lt;p&gt;The initialisation looks simple enough.&amp;nbsp; However, instead of one array of samples&amp;nbsp;p_event-&amp;gt;data.done.p_buffer[i] the&amp;nbsp;callback would need to return 2 arrays.&amp;nbsp; How&amp;nbsp;would&amp;nbsp;those values be accessed?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to read two analog inputs using SAADC?</title><link>https://devzone.nordicsemi.com/thread/188661?ContentTypeID=1</link><pubDate>Wed, 22 May 2019 20:34:02 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0e17546d-ff7d-497c-9a83-f709f2bedfd6</guid><dc:creator>Noah</dc:creator><description>&lt;p&gt;Figured it out earlier this morning! After the first reading, I unitialize SAADC and then instantly reinitialize it with my second analog pin as input, put both readings into a packet, transmit, then restart the whole process!&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/Image-from-iOS.png" /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to read two analog inputs using SAADC?</title><link>https://devzone.nordicsemi.com/thread/188462?ContentTypeID=1</link><pubDate>Wed, 22 May 2019 08:32:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:346b1808-baf2-40ff-b62a-8da0d6a04bcf</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;The SAADC peripheral will by default store samples directly in a buffer in RAM. I would recommend that you use scan mode (enabled automatically when more than one channel is enabled) with a buffer size of 2, and trigger a single sample to sample both channels. This will sample the channels successively with minimal delay, and you will get a done event once both channels have been samples. The callback will give a pointer to the buffer where the samples are stored.&lt;/p&gt;
&lt;p&gt;You can easily add more channels to the &lt;a href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.3.0/nrf_dev_saadc_example.html?cp=5_1_4_6_33"&gt;SAADC example in the SD&lt;/a&gt;K by adding these lines in saadc_init():&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;nrf_saadc_channel_config_t channel_config2 =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);

err_code = nrf_drv_saadc_channel_init(1, &amp;amp;channel_config);
APP_ERROR_CHECK(err_code);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;br /&gt;Jørgen&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to read two analog inputs using SAADC?</title><link>https://devzone.nordicsemi.com/thread/188393?ContentTypeID=1</link><pubDate>Wed, 22 May 2019 03:39:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a1c9f920-8370-4c45-8e04-6680211d0972</guid><dc:creator>paul</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; there are no doubt many ways to do this. In the following I am reading battery voltage and the presence of metal with a hall effect sensor.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define HALL_PIN NRF_SAADC_INPUT_AIN0               /// analog pin 0
#define VOLT_PIN NRF_SAADC_INPUT_AIN2               /// analog pin 2
#define VOLT_CHANNEL 0                              /// SAADC channel no
#define HALL_CHANNEL 1                              /// SAADC channel no

static nrf_saadc_channel_config_t ch_config_volts =  
              NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(VOLT_PIN);
static nrf_saadc_channel_config_t ch_config_hall =  
              NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(HALL_PIN);
static nrf_saadc_value_t adc_buf[2];        //!&amp;lt; Buffer used for storing ADC value.
static nrf_saadc_value_t volts_raw, hall_raw;

void saadc_init(void)
{    
    uint32_t err_code;
    nrfx_saadc_config_t saadc_config = NRFX_SAADC_DEFAULT_CONFIG;
   
    // Fine tune saadc params
    ch_config_volts.gain = NRF_SAADC_GAIN1_4;
    /// gain of a half produced range of ~0x75 compared to ~0x35 for quarter
    ch_config_hall.gain = NRF_SAADC_GAIN1_2;

    // init the adc
    err_code  = nrfx_saadc_init(&amp;amp;saadc_config, saadc_event_handler);
    // no point testing error.it is either success or complaining that it has been initialised

    // do a calibrate
    while (nrfx_saadc_calibrate_offset() != NRFX_SUCCESS)
        nrf_delay_ms(10);
    while (nrfx_saadc_is_busy())
        nrf_delay_ms(10);
    
    // config the adc channel to read cpu internal volts   
    err_code = nrfx_saadc_channel_init(VOLT_CHANNEL, &amp;amp;ch_config_volts);        
    APP_ERROR_CHECK(err_code);

    // config the adc channel to read hall sensor   
    err_code = nrf_drv_saadc_channel_init(HALL_CHANNEL, &amp;amp;ch_config_hall);        
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_buffer_convert(adc_buf, sizeof(adc_buf)/sizeof(nrf_saadc_value_t));
    APP_ERROR_CHECK(err_code);

    nrfx_saadc_sample();
}

/** @brief Function handling events from &amp;#39;nrf_drv_saadc.c&amp;#39;.
 *
 * @param[in] p_evt SAADC event.
 */
static void saadc_event_handler(nrf_drv_saadc_evt_t const * p_evt)
{
    if (p_evt-&amp;gt;type == NRFX_SAADC_EVT_DONE)
    {
        // just need to copy values now because could be overwritten at any time
        volts_raw = p_evt-&amp;gt;data.done.p_buffer[VOLT_CHANNEL];
        hall_raw = p_evt-&amp;gt;data.done.p_buffer[HALL_CHANNEL];
    } else if (p_evt-&amp;gt;type == NRFX_SAADC_EVT_CALIBRATEDONE) {
        // don&amp;#39;t do anything - we call calibrate every now and then and this comes back
    } else if (p_evt-&amp;gt;type ==  NRFX_SAADC_EVT_LIMIT) {
        // not setting any limits with nrfx_saadc_limits_set so should never fire
    }
}

/**
** @brief wrapper for saadc_get that returns the last voltage reading
** @param[out] p_vbatt returns the last voltage reading
**
*/
void saadc_get_volts(uint16_t * p_vbatt) {
    
    // convert and return the current volts
    *p_vbatt = ADC_RESULT_IN_MILLI_VOLTS(volts_raw);

    // schedule another go
    saadc_get();
}

/**
** @brief wrapper for saadc_get that returns the last hall effect reading
** @param[out] p_lvl_hall returns the last voltage reading
**
*/
void saadc_get_hall(uint16_t * p_lvl_hall) {
     
    // convert and return the hall value
    *p_lvl_hall = hall_raw;

    // schedule another go
    saadc_get();
}

/**
** @brief kick off the adc. value comes back in evt handler
** 
*/
static void saadc_get(void)
{
   ret_code_t err_code;

    // does the read which takes time 
    // value returned through the event handler
    if (!nrfx_saadc_is_busy())
    {
        err_code = nrfx_saadc_buffer_convert(adc_buf, sizeof(adc_buf)/sizeof(nrf_saadc_value_t));
        APP_ERROR_CHECK(err_code);

        nrfx_saadc_sample();
    }
}

&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I have no idea why I used two different calls to do the channel init - guess I was having a bad day at the time. They should probably both be the nrfx versions since they are the latest and greatest.&lt;/p&gt;
&lt;p&gt;Cheers Paul&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>