<?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>nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/105973/nrf52805-adc-polling-mode-issue</link><description>Hardware setup: Custom board using BC805M-P (with App protect) Software: nrf5 SDK S112 v17.0.2 -&amp;gt; Segger V7.30 
 My Objective: 
 measure the Li-ion battery voltage(4.2V -100% till 3.6V-0%) through an external resistive divider &amp;amp; internal 0.6v ref voltage</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 18 Sep 2024 13:31:45 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/105973/nrf52805-adc-polling-mode-issue" /><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/502949?ContentTypeID=1</link><pubDate>Wed, 18 Sep 2024 13:31:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:15fd76f0-0e35-4943-8aae-4ab3b034117d</guid><dc:creator>Gokulnath</dc:creator><description>&lt;p&gt;Hello,&lt;br /&gt;yes we did it indeed. the first value even before processing itself is moving a lot. either way we abandoned proceeding with this process.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;feel free to make this ticket unresolved.&lt;/p&gt;
&lt;p&gt;Thanks for your supports.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/500893?ContentTypeID=1</link><pubDate>Tue, 03 Sep 2024 08:12:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0ec089e5-8933-4e93-b525-cc9b1b3f2442</guid><dc:creator>helsing</dc:creator><description>&lt;p&gt;Hi Gokulnath, sorry for not replying in a long time.&lt;/p&gt;
&lt;p&gt;Going forward, it might be an idea to take a step back and look at the raw samples from SAADC. Could you try to take away all calculations in the code, in order to see what the raw samples from SAADC look like. Could you try a bench supply directly to the input, without a voltage divider in between? If the values look OK you can start adding one step at the time and see where the problem occurs.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/487496?ContentTypeID=1</link><pubDate>Wed, 05 Jun 2024 11:38:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:70510d11-7dff-4d08-b392-7780dda34ed7</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;&lt;span&gt;I corrected the hex float print and changed the % calculation to use mV and correct min &amp;amp; max for my test setup with 2032 coin cell&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;float volttopercent(float vadc)
{
  float Vmax = 3400; // mV was 4.2;
  float Vmin = 2700; // mV was3.63;
  float percentage;
  percentage = ((vadc -Vmin)/(Vmax - Vmin))*100;
  return percentage;
}&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Results look more sensible:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;-Raw SAADC-   ------Scaled------   ------Percent1----   -----Percent2------
 Dec   Hex    Decimal   Hex        Decimal   Hex        Decimal      Hex
==== ======   ======= ==========   ======= ==========   =======  ==========
2979 0x0BA3   2979.00 0x453A3000     39.86 0x421F6DB7     39.86  0x421F6DB7&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/487371?ContentTypeID=1</link><pubDate>Tue, 04 Jun 2024 16:32:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:54402b39-93ca-4af1-bf2f-694cdeb922d4</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Using the code posted with the floating-point percentage calculation: This data comes from your code using a 2.996 volt input (slightly different resistors, but that is not the point here):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;-Raw SAADC-   --------Scaled-------   --------Percent1-----    -------Percent2-----
 Dec   Hex     Decimal     Hex         Decimal      Hex         Decimal      Hex
==== ======   ========== ==========   ========== ==========    ========== ==========
2979 0x0BA3    2979.00   0x453A3000      39.86  0x421F6DB7       39.86 0x421F6DB7
2972 0x0B9C    2972.00   0x4539C000      38.86  0x421B6DB7       38.86 0x421B6DB7
2965 0x0B95    2965.00   0x45395000      37.86  0x42176DB7       37.86 0x42176DB7
2964 0x0B94    2964.00   0x45394000      37.71  0x4216DB6D       37.71 0x4216DB6D
2966 0x0B96    2966.00   0x45396000      38.00  0x42180000       38.00 0x42180000
2966 0x0B96    2966.00   0x45396000      38.00  0x42180000       38.00 0x42180000
with Burst 4 enabled
2981 0x0BA5    2981.00   0x453A5000      40.14  0x42209249       40.14 0x42209249
2970 0x0B9A    2970.00   0x4539A000      38.57  0x421A4925       38.57 0x421A4925
2972 0x0B9C    2972.00   0x4539C000      38.86  0x421B6DB7       38.86 0x421B6DB7
2965 0x0B95    2965.00   0x45395000      37.86  0x42176DB7       37.86 0x42176DB7
2966 0x0B96    2966.00   0x45396000      38.00  0x42180000       38.00 0x42180000
2966 0x0B96    2966.00   0x45396000      38.00  0x42180000       38.00 0x42180000
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;ints truncate floats; also as an aside floats (on the nRF52 hardware) are only 32-bit inclusive of sign and exponent, so have less precision than 32-bit ints. Compiler implicit conversion is compiler-dependent.&lt;/p&gt;
&lt;p&gt;The data above is generated by adding these lines to the code :&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Input range = (0.6 V)/(1)   = 0.6V -&amp;gt; 3.393 V with 931k/200K dividers
// 3.0 volts -&amp;gt; 14486 ADC counts with 14-bit sampling: 4828.8 counts per volt
#define ADC12_COUNTS_PER_VOLT 4829

    // Disable command &amp;amp; turn off the Power to ADC Bridge to reduce power consumption
    nrf_gpio_pin_write(ADC_SWITCH, 0); //Turning off the voltage divider transistor
    nrf_saadc_disable();
    nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    float f_result = (float)((buffer[0] * 1000L) * 1.667 * 16384);
    f_result = result; ///0.140625;
    int32_t i_result = result; ///0.140625;
    float percent_result1 = volttopercent(i_result);
    float percent_result2 = volttopercent(f_result);
    char InfoPacket[180] = &amp;quot;&amp;quot;;
    // -Raw SAADC-   -------Scaled-----   ------Percent1----   ------Percent2----
    //  Dec   Hex    Decimal   Hex        Decimal     Hex      Decimal    Hex
    // ==== ======   ======= ==========   ======= ==========   ======= ==========
    // 2968 0x0B98   2968.00 0x45398000     38.29 0x42192492     38.29 0x42192492
    snprintf(InfoPacket, sizeof(InfoPacket), &amp;quot;-Raw SAADC-   -------Scaled-----   ------Percent1----   ------Percent2----\r\n&amp;quot;);  uartSend(InfoPacket, strlen(InfoPacket));
    snprintf(InfoPacket, sizeof(InfoPacket), &amp;quot; Dec   Hex    Decimal   Hex        Decimal     Hex      Decimal    Hex\r\n&amp;quot;);     uartSend(InfoPacket, strlen(InfoPacket));
    snprintf(InfoPacket, sizeof(InfoPacket), &amp;quot;==== ======   ======= ==========   ======= ==========   ======= ==========\r\n&amp;quot;); uartSend(InfoPacket, strlen(InfoPacket));
    snprintf(InfoPacket, sizeof(InfoPacket), &amp;quot;%4d 0x%04X  %8.2f 0x%08X    %6.2f 0x%08X    %6.2f 0x%08X\r\n&amp;quot;, result, result, f_result, *(uint32_t *)&amp;amp;f_result, percent_result1, *(uint32_t *)&amp;amp;percent_result1, percent_result2, *(uint32_t *)&amp;amp;percent_result2);
    uartSend(InfoPacket, strlen(InfoPacket));&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;My post here is to show how to check the algorithm is doing the required actions ..&lt;/p&gt;
&lt;p&gt;Edit: I commented out the peculiar&amp;nbsp;0.140625 divider, correctd the hex float print and changed the % calc to use mV and correct min &amp;amp; max for my test setup&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/487316?ContentTypeID=1</link><pubDate>Tue, 04 Jun 2024 12:22:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2b45c588-a3af-4c1e-8008-0d35b4cd3b53</guid><dc:creator>Gokulnath</dc:creator><description>&lt;p&gt;Hey&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/members/hahe"&gt;helsing&lt;/a&gt;&amp;nbsp;,&lt;br /&gt;Thanks for the suggestion I&amp;#39;ve also added the calibration too..&lt;br /&gt;&lt;br /&gt;my new code below along with my New Hardware. But i have a few questions so asked them below (next thread)&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;// Input range of internal Vdd measurement = (0.6 V)/(1) = 0.6 V MAX in External Resistor Divider Output.
// 16384 ADC counts with 14-bit sampling:  0.1v = 2730.6 ADC Counts
// Resistor Divider 2.2M &amp;amp; 360K
// 4.2V  =&amp;gt; 0.591 volts -&amp;gt; Assuming 100% Battery SoC
// 3.63V =&amp;gt; 0.51 Volts -&amp;gt; Assuming 0% Battery SoC
//  Vadc= Vbat * ((360K)/(360K+2M2)) =&amp;gt; Vadc = Vbat * 0.140625

void Adc12bitPolledInitialise(void)
{
    uint32_t timeout = 10;
    nrf_saadc_channel_config_t myConfig =
    {
        .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
        .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
        .gain       = NRF_SAADC_GAIN1,              //  1 Gain
        .reference  = NRF_SAADC_REFERENCE_INTERNAL, // 0.6V internal Ref Voltage
        .acq_time   = NRF_SAADC_ACQTIME_40US,       // See max source resistancetable
        .mode       = NRF_SAADC_MODE_SINGLE_ENDED,
        .burst      = NRF_SAADC_BURST_DISABLED,
        .pin_p      = NRF_SAADC_INPUT_AIN3,         // AIN3 for input Pin
        .pin_n      = NRF_SAADC_INPUT_DISABLED
    };

    nrf_saadc_resolution_set((nrf_saadc_resolution_t) 3);   // 2 is 12-bit , 3 for 14-bit 
    //nrf_saadc_oversample_set((nrf_saadc_oversample_t) 2);   // 2 is 4x, about 150uSecs total
    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
    nrf_saadc_enable();

    NRF_SAADC-&amp;gt;CH[1].CONFIG =
              ((myConfig.resistor_p &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESP_Pos)   &amp;amp; SAADC_CH_CONFIG_RESP_Msk)
            | ((myConfig.resistor_n &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESN_Pos)   &amp;amp; SAADC_CH_CONFIG_RESN_Msk)
            | ((myConfig.gain       &amp;lt;&amp;lt; SAADC_CH_CONFIG_GAIN_Pos)   &amp;amp; SAADC_CH_CONFIG_GAIN_Msk)
            | ((myConfig.reference  &amp;lt;&amp;lt; SAADC_CH_CONFIG_REFSEL_Pos) &amp;amp; SAADC_CH_CONFIG_REFSEL_Msk)
            | ((myConfig.acq_time   &amp;lt;&amp;lt; SAADC_CH_CONFIG_TACQ_Pos)   &amp;amp; SAADC_CH_CONFIG_TACQ_Msk)
            | ((myConfig.mode       &amp;lt;&amp;lt; SAADC_CH_CONFIG_MODE_Pos)   &amp;amp; SAADC_CH_CONFIG_MODE_Msk)
            | ((myConfig.burst      &amp;lt;&amp;lt; SAADC_CH_CONFIG_BURST_Pos)  &amp;amp; SAADC_CH_CONFIG_BURST_Msk);

    NRF_SAADC-&amp;gt;CH[1].PSELN = myConfig.pin_n;
    NRF_SAADC-&amp;gt;CH[1].PSELP = myConfig.pin_p;
}

void ble_Update_BatteryVoltage(void)
{
    nrf_saadc_enable();

    nrf_delay_ms(100); // add a delay to make the capacitor charge 

    volatile float result = 0;              // Some recognisable dummy value
    uint32_t timeout = 1000000;       // Trial and error
    volatile int32_t buffer[10];

    NRF_SAADC-&amp;gt;RESULT.PTR = (uint32_t)buffer;
    NRF_SAADC-&amp;gt;RESULT.MAXCNT = 1;

    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_START);   // Start the SAADC to prepare for sampling

    // Wait until the SAADC is ready (EVENT_STARTED is set)
    while (!nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) &amp;amp;&amp;amp; !nrf_saadc_event_check(NRF_SAADC_EVENT_CALIBRATEDONE)) 
    {
        // Optionally, you could add a timeout mechanism here to avoid waiting indefinitely
    }

    nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);  // Trigger the SAADC to take a sample now that it is ready

    while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) &amp;amp;&amp;amp; timeout &amp;gt; 0)
    {
        timeout--;
    }

    if (timeout != 0)
    {
        //result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/2)) / ADC12_COUNTS_PER_VOLT;
        result = (float)((buffer[0] * 1000L) * 1.667 * 16384);
        result = result/0.140625;
        result = volttopercent(result);
    }

    nrf_saadc_disable();

    nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);  // Clear the STARTED event to enable detection next time
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    
    /*
    while(result&amp;gt;100 &amp;amp;&amp;amp; result &amp;gt;0)
    {
    result = result%100;
    }
    */
         
    if(Old_Bat != result &amp;amp;&amp;amp; result &amp;gt;=1 &amp;amp;&amp;amp; result !=0)
    {

    if(result&amp;lt;=5)
    {
    //result = 5;
    nrf_gpio_pin_write(BLUE_LED, 0); //Turning on the LOW BAttery Flash LED
    nrf_delay_ms(1000); // add a delay to make the capacitor charge 
    nrf_gpio_pin_write(BLUE_LED, 1); //Turning off the LOW BAttery Flash LED   
    }
    
    Old_Bat = result;
    ble_bas_battery_level_update(&amp;amp;m_bas, result, m_conn_handle);
    }
    nrf_saadc_task_trigger(NRF_SAADC_TASK_CALIBRATEOFFSET);
}

float volttopercent(float vadc)
{
  float Vmax = 4.2;
  float Vmin = 3.63;
  
  float percentage;

  percentage = ((vadc -Vmin)/(Vmax - Vmin))*100;

  return percentage;
}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I&amp;#39;m still testing it so dont know the results 100% yet.&lt;br /&gt;Thanks&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/487255?ContentTypeID=1</link><pubDate>Tue, 04 Jun 2024 09:41:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4e5b38b0-1c61-4a81-bb24-723beee022fd</guid><dc:creator>Gokulnath</dc:creator><description>&lt;p&gt;Hey&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/members/hmolesworth"&gt;hmolesworth&lt;/a&gt;&amp;nbsp;&lt;br /&gt;Could you precise your ADC Config? more precisely the ADC reference Voltage?&lt;br /&gt;&lt;br /&gt;also, question on this:&lt;br /&gt;from Datasheet of nrf52805:&amp;nbsp;&lt;br /&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1717495758907v1.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;My implemented formula:&lt;/strong&gt; &lt;span&gt;(for gain 1.5 &amp;amp; 0.6V REF Voltage for the above voltage divider of 220K &amp;amp; 36K? on a 4.2V Battery)&lt;/span&gt;&lt;br /&gt;result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/2)) / ADC12_COUNTS_PER_VOLT;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;is the above correct?&lt;/strong&gt; I think my gain might be incorrect!&amp;nbsp; where&amp;nbsp;&lt;strong&gt;My Desired Battery voltage range is this:&amp;nbsp;4.2V 100% =&amp;gt; 3.63V 0%&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;or should it be like this?&lt;/strong&gt; (for gain 1 &amp;amp; 0.6V REF Voltage for the above voltage divider of 220K &amp;amp; 36K? on a 4.2V Battery )&lt;br /&gt;&lt;span&gt;result = ((buffer[0] * 1000L) * 1.667 * 16384);&lt;br /&gt;&lt;br /&gt;Vadc= Vbat * ((360K)/(360K+2M2)) =&amp;gt; Vadc = Vbat * 0.140625&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;// Input range of internal Vdd measurement = (0.6 V)/(1) = 0.6 V MAX in External Resistor Divider Output.
// 16384 ADC counts with 14-bit sampling:  0.1v = 2730.6 ADC Counts
// Resistor Divider 2.2M &amp;amp; 360K
// 4.2V  =&amp;gt; 0.591 volts -&amp;gt; Assuming 100% Battery SoC
// 3.63V =&amp;gt; 0.51 Volts -&amp;gt; Assuming 0% Battery SoC
// 


if (timeout != 0)
    {
        //result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/2)) / ADC12_COUNTS_PER_VOLT;
        result = (float)((buffer[0] * 1000L) * 1.667 * 16384);
        result = result/0.140625;
        result = volttopercent(result);
    }
    
    float volttopercent(float vadc)
{
  float Vmax = 4.2;
  float Vmin = 3.63;
  
  float percentage;

  percentage = ((vadc -Vmin)/(Vmax - Vmin))*100;

  return percentage;
}

// NOW RESULT SHOULD send VBat in terms of custom % ?&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I&amp;#39;m using the internal chip 0.6V.&amp;nbsp; I shall do the test on my side with this added info &amp;amp; shall post the results here.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;*******************************************************************************************************************************&lt;br /&gt;See the below thread too for my reply to Helsing&lt;br /&gt;&lt;br /&gt;Thanks.&lt;br /&gt;Gokulnath A R&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/487190?ContentTypeID=1</link><pubDate>Tue, 04 Jun 2024 02:23:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:053a4dbb-ad71-4702-bbf3-a4e50db9a6bc</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;By making a tiny change and masking out some of your code the raw SAADC results look ok to me without using bust mode or averaging or filtering (using 931k and 200k, so similar):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;Battery 2984
Battery 2982
Battery 2966
Battery 2969
Battery 2973
Battery 2964
Battery 2965
Battery 2970
Battery 2968
Battery 2960
Battery 2960
Battery 2958
Battery 2966
Battery 2961
Battery 2960
Battery 2965
Battery 2970&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I made these simple changes:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;    .gain       = NRF_SAADC_GAIN1, // Gain (was 1.5)

    volatile int16_t buffer[20]; // 16-bit signed, not 32-bit signed&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I commented out the maths and added a print:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    // Add a printout to test raw data
    char InfoPacket[120] = &amp;quot;&amp;quot;;
    snprintf(InfoPacket, sizeof(InfoPacket), &amp;quot;Battery %4d\r\n&amp;quot;, result);
    uartSend(InfoPacket, strlen(InfoPacket));
    // Remove the odd maths stuff, that&amp;#39;s a non-SAADC issue
//  while(result&amp;gt;100 &amp;amp;&amp;amp; result &amp;gt;0)
//  {
//  result = result%100;
//  }
//  if(Old_Bat != result &amp;amp;&amp;amp; result &amp;gt;=1 &amp;amp;&amp;amp; result !=0)
//  {
//  if(result&amp;lt;=17)
//  {
//  result = 5;
//  nrf_gpio_pin_write(BLUE_LED, 0); //Turning on the LOW BAttery Flash LED
//  nrf_delay_ms(1000); // add a delay to make the capacitor charge
//  nrf_gpio_pin_write(BLUE_LED, 1); //Turning off the LOW BAttery Flash LED
//  }
//  Old_Bat = result;
//  ble_bas_battery_level_update(&amp;amp;m_bas, result, m_conn_handle);
//  }
}
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/487125?ContentTypeID=1</link><pubDate>Mon, 03 Jun 2024 12:41:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:93a71a72-260a-4125-a6ac-ef1f90b3b4b1</guid><dc:creator>helsing</dc:creator><description>&lt;p&gt;Hi Gokulnath, sorry for the long delay.&lt;/p&gt;
&lt;p&gt;What are the reslults from your lateste updated code?&lt;/p&gt;
&lt;p&gt;Anyways, looking over this thread, somthing that seems to be missing is the wait for the SAADC to be ready, by checking for the &lt;code&gt;NRF_SAADC_EVENT_STARTED&lt;/code&gt; event. By adding a check for the NRF_SAADC_EVENT_STARTED event before initiating sampling, you can ensure that the ADC has fully powered up and stabilized:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;// Start the SAADC to prepare for sampling
nrf_saadc_task_trigger(NRF_SAADC_TASK_START);

// Wait until the SAADC is ready (EVENT_STARTED is set)
while (!nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED)) {
    // Optionally, you could add a timeout mechanism here to avoid waiting indefinitely
}

// Clear the STARTED event to enable detection next time
nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);

// Trigger the SAADC to take a sample now that it is ready
nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/478587?ContentTypeID=1</link><pubDate>Fri, 12 Apr 2024 14:52:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:70970bb6-dd73-453f-ad5e-ffdef16dac14</guid><dc:creator>Gokulnath</dc:creator><description>&lt;p&gt;Hey,&lt;br /&gt;&lt;br /&gt;Sorry for my delay in updating this thread with my hardware changes.&lt;br /&gt;&lt;br /&gt;Just an update I&amp;#39;ve updated the custom PCB to this &amp;amp; This would be my current most updated hardware setting.&lt;br /&gt;&lt;br /&gt;I &lt;span style="color:#ff6600;"&gt;haven&amp;#39;t&lt;/span&gt; implemented your filter on the software yet.&lt;br /&gt;&lt;br /&gt;With this current configuration &lt;span style="background-color:#ffff00;color:#000000;"&gt;(2 versions of Custom PCB),&lt;/span&gt; I have an &lt;span style="color:#ff6600;"&gt;oscillation delta of +-8%&lt;/span&gt;&amp;nbsp;&lt;span style="background-color:#ffff00;color:#000000;"&gt;in both versions PCB from the true battery charge %.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff00ff;"&gt;(Just incase I&amp;#39;ve shunted the Transistor too(For Testing purposes) to see if it makes any change in output BUT the result remains the same)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff6600;"&gt;In Both Versions of PCB the ADC Voltage Divider Ratio is the same.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;Version 1 with ADC Switch PCB Below:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1712933371195v1.png" /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#ff0000;"&gt;Version 2 without Transistor Switch PCB Below:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1717068445033v1.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="background-color:#ff6600;"&gt;In Both Versions of the PCB I&amp;#39;ve added Ferrite Beads for EMC stability like shown below&lt;/span&gt; (Ofc Version 2 PCB doesn&amp;#39;t have ADC switch input like shown below.)&lt;span style="background-color:#ff6600;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1717068713283v1.png" /&gt;&lt;br /&gt;&lt;br /&gt;My current ADC input is &lt;span style="color:#ff6600;"&gt;&lt;strong&gt;AIN3.&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My Desired Battery voltage range is this: &lt;span style="color:#ff6600;"&gt;4.2V 100% =&amp;gt; 3.63V 0%&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;I explicitly add a software delay to make the capacitor charge too to avoid any inconsistencies in the hardware voltage level.&lt;br /&gt;&lt;br /&gt;my latest adc&amp;nbsp;code is below:&lt;br /&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1712933449493v2.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;void Adc12bitPolledInitialise(void)
{
    uint32_t timeout = 10;
    nrf_saadc_channel_config_t myConfig =
    {
        .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
        .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
        .gain       = NRF_SAADC_GAIN1_5,            // (1/5) Gain
        .reference  = NRF_SAADC_REFERENCE_INTERNAL, // 0.6V internal Ref Voltage
        .acq_time   = NRF_SAADC_ACQTIME_40US,       // See max source resistancetable
        .mode       = NRF_SAADC_MODE_SINGLE_ENDED,
        .burst      = NRF_SAADC_BURST_DISABLED,
        .pin_p      = NRF_SAADC_INPUT_AIN3,         // AIN3 for input Pin
        .pin_n      = NRF_SAADC_INPUT_DISABLED
    };

    nrf_saadc_resolution_set((nrf_saadc_resolution_t) 3);   // 2 is 12-bit , 3 for 14-bit 
    //nrf_saadc_oversample_set((nrf_saadc_oversample_t) 2);   // 2 is 4x, about 150uSecs total
    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
    nrf_saadc_enable();

    NRF_SAADC-&amp;gt;CH[1].CONFIG =
              ((myConfig.resistor_p &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESP_Pos)   &amp;amp; SAADC_CH_CONFIG_RESP_Msk)
            | ((myConfig.resistor_n &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESN_Pos)   &amp;amp; SAADC_CH_CONFIG_RESN_Msk)
            | ((myConfig.gain       &amp;lt;&amp;lt; SAADC_CH_CONFIG_GAIN_Pos)   &amp;amp; SAADC_CH_CONFIG_GAIN_Msk)
            | ((myConfig.reference  &amp;lt;&amp;lt; SAADC_CH_CONFIG_REFSEL_Pos) &amp;amp; SAADC_CH_CONFIG_REFSEL_Msk)
            | ((myConfig.acq_time   &amp;lt;&amp;lt; SAADC_CH_CONFIG_TACQ_Pos)   &amp;amp; SAADC_CH_CONFIG_TACQ_Msk)
            | ((myConfig.mode       &amp;lt;&amp;lt; SAADC_CH_CONFIG_MODE_Pos)   &amp;amp; SAADC_CH_CONFIG_MODE_Msk)
            | ((myConfig.burst      &amp;lt;&amp;lt; SAADC_CH_CONFIG_BURST_Pos)  &amp;amp; SAADC_CH_CONFIG_BURST_Msk);

    NRF_SAADC-&amp;gt;CH[1].PSELN = myConfig.pin_n;
    NRF_SAADC-&amp;gt;CH[1].PSELP = myConfig.pin_p;
    nrf_gpio_pin_write(ADC_SWITCH, 1); //Turning on  the voltage divider with a transistor
}

void ble_Update_BatteryVoltage(void)
{
    // Enable command &amp;amp; Turn on the Power
    nrf_gpio_pin_write(ADC_SWITCH, 1); //Turning on  the voltage divider with a transistor
    nrf_saadc_enable();

    nrf_delay_ms(100); // add a delay to make the capacitor charge 

    uint16_t result = 0;              // Some recognisable dummy value
    uint32_t timeout = 1000000;       // Trial and error
    volatile int32_t buffer[20];

    NRF_SAADC-&amp;gt;RESULT.PTR = (uint32_t)buffer;
    NRF_SAADC-&amp;gt;RESULT.MAXCNT = 1;

    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);

    while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) &amp;amp;&amp;amp; timeout &amp;gt; 0)
    {
        timeout--;
    }

    if (timeout != 0)
    {
        result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/2)) / ADC12_COUNTS_PER_VOLT;
        result += 5;
    }

    // Disable command &amp;amp; turn off the Power to ADC Bridge to reduce power consumption
    nrf_gpio_pin_write(ADC_SWITCH, 0); //Turning off the voltage divider transistor
    nrf_saadc_disable();

    nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    
    while(result&amp;gt;100 &amp;amp;&amp;amp; result &amp;gt;0)
    {
    result = result%100;
    }
    
    if(Old_Bat != result &amp;amp;&amp;amp; result &amp;gt;=1 &amp;amp;&amp;amp; result !=0)
    {

    if(result&amp;lt;=17)
    {
    result = 5;
    nrf_gpio_pin_write(BLUE_LED, 0); //Turning on the LOW BAttery Flash LED
    nrf_delay_ms(1000); // add a delay to make the capacitor charge 
    nrf_gpio_pin_write(BLUE_LED, 1); //Turning off the LOW BAttery Flash LED   
    }
    
    Old_Bat = result;
    ble_bas_battery_level_update(&amp;amp;m_bas, result, m_conn_handle);
    }
    
}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Since I thought there was a fundamental problem with my code/hardware configuration I didn&amp;#39;t add the software filter yet.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;if there seems to be no fundamental error on this config I shall proceed to add the software filter which you guys suggested.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff6600;"&gt;In this above code, I&amp;#39;ve just added some phantom code to round off the results + some offset so that the result always comes between 0-100% on BLE.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;especially here below:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;while(result&amp;gt;100 &amp;amp;&amp;amp; result &amp;gt;0)
    {
    result = result%100;
    }
    
    if(Old_Bat != result &amp;amp;&amp;amp; result &amp;gt;=1 &amp;amp;&amp;amp; result !=0)
    {

    if(result&amp;lt;=17)
    {
    result = 5;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff00ff;"&gt;P.S.&lt;/span&gt; If you need a log for this setup I can provide you with one. (the previous log in this forum thread is not from this latest setup)&lt;br /&gt;&lt;br /&gt;Thanks in advance,&lt;br /&gt;Gokulnath A R&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/478346?ContentTypeID=1</link><pubDate>Thu, 11 Apr 2024 13:41:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4c0a409c-e47f-41e1-bf24-35a96bfb29e1</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;There is a typo in this line, which was correct in your earlier post. Also note that this is not averaging, it is rounding; this means the averaging is presumably performed in&amp;nbsp;&lt;em&gt;ble_bas_battery_level_update()&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// This line rounds the reading
Change
    result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/5)) / ADC12_COUNTS_PER_VOLT;
To
    result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/2)) / ADC12_COUNTS_PER_VOLT;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You can add the averaging I posted earlier, something like this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void LowPassFilter(uint16_t *FilteredValue, result);

// Measured battery voltage - filtered value
static uint16_t MeasuredBatteryVoltage = 0;

    if (timeout != 0)
    {
        result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/2)) / ADC12_COUNTS_PER_VOLT;
        LowPassFilter(&amp;amp;MeasuredBatteryVoltage, result);
        // Use filtered value instead of raw sample
        result = MeasuredBatteryVoltage;
    }
.. snip ..
    ble_bas_battery_level_update(&amp;amp;m_bas, result, m_conn_handle); 

    return result;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Edit: If using the circuit first posted,&amp;nbsp; the numbers in the log don&amp;#39;t look correct:&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/1401.WhatsApp-Image-2023_2D00_11_2D00_22-at-16.40.02.jpeg_2D00_640x480.jpg_2D00_640x480.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;Vadc = Vbat*300/(120+300) = (Vbat*300)/420
Vadc411 = 2936 mV
Vadc368 = 2629 mV

// Input range of internal Vdd measurement = (0.6 V)/(1/5) = 3 V
// 3.0 volts -&amp;gt;  16383 ADC counts with 14-bit sampling:  5461 counts per volt
// 3.0 volts -&amp;gt;   4095 ADC counts with 14-bit sampling:  1365 counts per volt
Vadc411 = 2936 mV = 16033 counts with 14-bit sampling
Vadc411 = 2936 mV =  4007 counts with 12-bit sampling

result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/2)) / ADC12_COUNTS_PER_VOLT;
result411 = ((16033 * 1000)+(5461/2))/5461 = 2936 with 14-bit sampling
result411 = (( 4007 * 1000)+(1365/2))/1365 = 2936 with 12-bit sampling
Vbat = 2936 * (120+300)/300 = 4110 mV = 4.11 V

From the log:
Voltage on BLE // 4.11V on voltage divider input from a Bench Power supply.
I      0BLEParserBase.CopyToRawData:Data:0x76  &amp;lt;&amp;lt;== 118, should be 0x678 for 14-bit, 0x555 for 12-bit&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Maybe explicitly cast to uint32_t to ensure 32-bit processing:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Ensure 32-bit processing:
result = (uint16_t)(((uint32_t)buffer[0] * 1000UL)+((uint32_t)ADC12_COUNTS_PER_VOLT/2)) / (uint32_t)ADC12_COUNTS_PER_VOLT);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/members/hahe"&gt;Helsing&lt;/a&gt;&amp;#39;s suggestion of printing out intermediate steps is the best way to verify the code is doing what you expect.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/478321?ContentTypeID=1</link><pubDate>Thu, 11 Apr 2024 12:41:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:512589df-8a9c-4d6b-97a3-992ee64a435d</guid><dc:creator>helsing</dc:creator><description>&lt;p&gt;Hi Gokulnath, sorry for the delay.&lt;/p&gt;
&lt;p&gt;Some context is missing. However, it looks like you are performing many steps in only a few lines. Why not break up the calculations and print out the intermediate values? That way you could confirm that you are performing the intended calculations.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/476201?ContentTypeID=1</link><pubDate>Wed, 27 Mar 2024 15:22:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8522af52-69e6-4f17-9169-0e32563d4b9c</guid><dc:creator>Gokulnath</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/members/hmolesworth"&gt;hmolesworth&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/members/hahe"&gt;helsing&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;I&amp;#39;ve noticed in debugging that my averaging might not be correct due to that I suspect it&amp;#39;s moving a lot.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;can you please verify it,&lt;pre class="ui-code" data-mode="text"&gt;    if (timeout != 0)
    {
        result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/
        5)) / ADC12_COUNTS_PER_VOLT;
    }&lt;/pre&gt;&amp;nbsp;especially this line?&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;EDIT:&lt;/span&gt;&lt;br /&gt;sorry there was my typo during copy pasting the code in this thread. my correct code is still this.&lt;br /&gt;&lt;br /&gt;result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/&lt;span style="color:#ff6600;"&gt;2&lt;/span&gt;)) / ADC12_COUNTS_PER_VOLT;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thanks,&lt;br /&gt;Gokulnath A R&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/457665?ContentTypeID=1</link><pubDate>Mon, 27 Nov 2023 17:06:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:82154466-5371-41ef-b5ac-9049d201741f</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;I wrote this filter for a similar application; try it to see if it gives you what you are looking for&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Limit excursions such as noise spikes; for a step change this enforces a
// linear ramp or descent
// For 250 mVolts, 3300mV FSD and 12-bit ADC =&amp;gt; ((250*4096)/3300) = 310
#define NOISE_SPIKE_CLIP_VALUE  310

// Equaliser single-pole low-pass filter value (0 is off). Increasing this value
// might require checking not overranging variables which FILTER_VALUE is assigned to.
#define FILTER_VALUE  16

#define FILTER_HOLDOFF_TRIP_LEVEL 16

// ADC Filter initial hold-off counter
uint16_t FilterHoldoffCounter = 0;
// Measured battery voltage - filtered value
uint16_t MeasuredBatteryVoltage;

void LowPassFilter(uint16_t *FilteredValue, uint16_t NewValue)
/*
 * This function implements a slew-rate limiting noise spike filter
 * followed by a single pole low-pass filter.
 *
 * Noise Spike Filter:
 *
 * Clip any signals to remain within 0.x volts of current filtered value
 *
 * Single-pole low-pass filter:
 *
 *    FV = ((1-n)*FV + n*V)/n where n=1/FILTER_VALUE
 *
 * The filter kicks in after 5 time constants which allows the filter to
 * settle to 12-bit resolution before taking over
 *
 * If FILTER_VALUE is constrained to lie between 0 (off) and 32 then 16-bit
 * unsigned arithmetic may be used since with a full-scale input reading
 * of 0x07FF (32-1)*0x7FF + 0x7FF + (32/2) = 65520 which fits in 16-bits
 * Otherwise 32-bit calculation is required. For ARM use 32-bit always
 */
{
    uint16_t LocalFilteredValue = *FilteredValue;
    uint16_t SpikeClippedValue;

    // Set initial value to be spike-clipped (slew-rate limited)
    SpikeClippedValue = NewValue;

    // Check if new value is above or below above current filtered value
    if (NewValue &amp;gt;= LocalFilteredValue)    // +ve signal excursion
    {
        // Clip input if more than 0.5 volts above current filtered value
        if (NewValue &amp;gt; LocalFilteredValue + NOISE_SPIKE_CLIP_VALUE)
        {
            SpikeClippedValue = LocalFilteredValue + NOISE_SPIKE_CLIP_VALUE;
        }
    }
    else  // -ve signal excursion
    {
        // Clip input if more than 0.5 volts below current filtered value
        if ((LocalFilteredValue - NewValue) &amp;gt; NOISE_SPIKE_CLIP_VALUE)
        {
            SpikeClippedValue = LocalFilteredValue - NOISE_SPIKE_CLIP_VALUE;
        }
    }

    // Either no filter or no processing required for speed, just return value
    #if (!FILTER_VALUE) //|| defined(USE_ADC12B_MULTIPLE_SAMPLES)
    {
        *FilteredValue = SpikeClippedValue;  // Filter disabled
        return;
    }
    #else //if (!FILTER_VALUE)

    LocalFilteredValue = (LocalFilteredValue*(FILTER_VALUE-1))
                       + SpikeClippedValue + (FILTER_VALUE/2);
    LocalFilteredValue /= FILTER_VALUE;

    // Filter settles to final 12-bit value within 5 time-constants, check ready
    // This is only used on exit hibernate and initial power-on cold start where
    // all channels are continually read to condition the filters. Prior to that
    // FilterHoldoffCounter must be initialized to 0.
    if ( FilterHoldoffCounter &amp;gt; FILTER_HOLDOFF_TRIP_LEVEL )
    {
        *FilteredValue = LocalFilteredValue;
    }
    else
    {
        FilterHoldoffCounter++;          // Waiting for initial stable reading
        *FilteredValue = NewValue;
    }
    #endif //if (!FILTER_VALUE)
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/457661?ContentTypeID=1</link><pubDate>Mon, 27 Nov 2023 16:54:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:28984716-e9d2-4b0b-80b7-4ac65a92b6b7</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;BLE transmissions require current bursts, and even small such current bursts load the battery and are observable as voltage dips due to internal battery impedance which show up as disturbances in the measured voltage readings. Several options to reduce these voltage measurement dips: 1) sample the SAADC prior to a BLE burst (see Radio events); 2) add a filter capacitor between ADC IN 2 (AIN) and GND eg 100nF or more. Time constant of 100nF with 120k to battery is 12mSec, but for battery measurement probably an even slower value would be acceptable. The bigger the capacitor, the more even the voltage readings. 3) Use averaging; averaging is always better and for battery capacity response time is not significant.&lt;/p&gt;
&lt;p&gt;Often two battery indications are required; battery voltage for capacity and lowest voltage dip for pending reset or brownout problems. Use averaging for the former and single values for the latter. Maybe even use 2 SAADC inputs, one with filter capacitor and one not to allow both fast sampling via comparator or SAADC and one for slower voltage measurement for capacity, probably overkill.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/457486?ContentTypeID=1</link><pubDate>Mon, 27 Nov 2023 09:05:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1b10e1d1-7d2a-4370-9cde-0aed74b3c602</guid><dc:creator>Gokulnath</dc:creator><description>&lt;p&gt;Hey,&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve&amp;nbsp;made these suggested changes.&lt;a href="https://devzone.nordicsemi.com/members/hmolesworth"&gt;hmolesworth&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Ofc the value oscillation is better than before but still, it moves a lot.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;-&amp;gt;My voltage bridge is always on for this particular test &amp;amp; I verified it on the Circuit level during operation&lt;br /&gt;&lt;br /&gt;My new code below:&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;// Input range of internal Vdd measurement = (0.6 V)/(1/5) = 3 V
// 3.0 volts -&amp;gt;  16383 ADC counts with 14-bit sampling:  5461 counts per volt
// 3.0 volts -&amp;gt;  4095 ADC counts with 14-bit sampling:  1365 counts per volt

#define ADC12_COUNTS_PER_VOLT 5461

void Adc12bitPolledInitialise(void)
{
    uint32_t timeout = 10;
    nrf_saadc_channel_config_t myConfig =
    {
        .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
        .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
        .gain       = NRF_SAADC_GAIN1_5,            // (1/5) Gain
        .reference  = NRF_SAADC_REFERENCE_INTERNAL, // 0.6V internal Ref Voltage
        .acq_time   = NRF_SAADC_ACQTIME_40US,       // See max source resistancetable
        .mode       = NRF_SAADC_MODE_SINGLE_ENDED,
        .burst      = NRF_SAADC_BURST_DISABLED,
        .pin_p      = NRF_SAADC_INPUT_AIN2,         // AIN2 for input Pin
        .pin_n      = NRF_SAADC_INPUT_DISABLED
    };

    nrf_saadc_resolution_set((nrf_saadc_resolution_t) 3);   // 2 is 12-bit , 3 for 14-bit 
    //nrf_saadc_oversample_set((nrf_saadc_oversample_t) 2);   // 2 is 4x, about 150uSecs total
    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
    nrf_saadc_enable();

    NRF_SAADC-&amp;gt;CH[1].CONFIG =
              ((myConfig.resistor_p &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESP_Pos)   &amp;amp; SAADC_CH_CONFIG_RESP_Msk)
            | ((myConfig.resistor_n &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESN_Pos)   &amp;amp; SAADC_CH_CONFIG_RESN_Msk)
            | ((myConfig.gain       &amp;lt;&amp;lt; SAADC_CH_CONFIG_GAIN_Pos)   &amp;amp; SAADC_CH_CONFIG_GAIN_Msk)
            | ((myConfig.reference  &amp;lt;&amp;lt; SAADC_CH_CONFIG_REFSEL_Pos) &amp;amp; SAADC_CH_CONFIG_REFSEL_Msk)
            | ((myConfig.acq_time   &amp;lt;&amp;lt; SAADC_CH_CONFIG_TACQ_Pos)   &amp;amp; SAADC_CH_CONFIG_TACQ_Msk)
            | ((myConfig.mode       &amp;lt;&amp;lt; SAADC_CH_CONFIG_MODE_Pos)   &amp;amp; SAADC_CH_CONFIG_MODE_Msk)
            | ((myConfig.burst      &amp;lt;&amp;lt; SAADC_CH_CONFIG_BURST_Pos)  &amp;amp; SAADC_CH_CONFIG_BURST_Msk);

    NRF_SAADC-&amp;gt;CH[1].PSELN = myConfig.pin_n;
    NRF_SAADC-&amp;gt;CH[1].PSELP = myConfig.pin_p;
    nrf_gpio_pin_write(ADC_SWITCH, 1); //Turning on  the voltage divider with a transistor
}

void ble_Update_BatteryVoltage(void)
{
    // Enable command &amp;amp; Turn on the Power
    //nrf_gpio_pin_write(ADC_SWITCH, 1); //Turning on  the voltage divider with a transistor
    nrf_saadc_enable();

    uint16_t result = 9999;         // Some recognisable dummy value
    uint32_t timeout = 100000;       // Trial and error
    volatile int16_t buffer[100];

    NRF_SAADC-&amp;gt;RESULT.PTR = (uint32_t)buffer;
    NRF_SAADC-&amp;gt;RESULT.MAXCNT = 1;

    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);

    while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) &amp;amp;&amp;amp; timeout &amp;gt; 0)
    {
        timeout--;
    }

    if (timeout != 0)
    {
        result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/2)) / ADC12_COUNTS_PER_VOLT;
    }

    nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);

    // Disable command &amp;amp; turn off the Power to ADC Bridge to reduce power consumption
    nrf_saadc_disable();
    
    //nrf_gpio_pin_write(ADC_SWITCH, 0); //Turning off the voltage divider transistor
    ble_bas_battery_level_update(&amp;amp;m_bas, result, m_conn_handle); 
}

&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Regarding the example output which you asked&amp;nbsp;&lt;/strong&gt;&lt;a href="https://devzone.nordicsemi.com/members/hahe"&gt;helsing&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;I&amp;#39;ve just parsed the output of the Battery for each button press on the BLE terminal into the txt file for simpler understanding. (&lt;strong&gt;All the numbers are in hex format)&lt;/strong&gt;&lt;/p&gt;
[quote userid="90815" url="~/f/nordic-q-a/105973/nrf52805-adc-polling-mode-issue/457197"]What does this look like? Would you be able to provide an example? Does the this change if you change the voltage?[/quote]
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;Voltage on BLE // 4.11V on voltage divider input from a Bench Power supply.
I      0BLEParserBase.CopyToRawData:Data:0x76
I      0BLEParserBase.CopyToRawData:Data:0x79
I      0BLEParserBase.CopyToRawData:Data:0x89
I      0BLEParserBase.CopyToRawData:Data:0x73
I      0BLEParserBase.CopyToRawData:Data:0x75
I      0BLEParserBase.CopyToRawData:Data:0x75
I      0BLEParserBase.CopyToRawData:Data:0x7A
I      0BLEParserBase.CopyToRawData:Data:0x6B
I      0BLEParserBase.CopyToRawData:Data:0x75
I      0BLEParserBase.CopyToRawData:Data:0x7B
I      0BLEParserBase.CopyToRawData:Data:0x7E
I      0BLEParserBase.CopyToRawData:Data:0x78

Voltage on BLE // 3.68V on voltage divider input from  a Bench Power supply.

I      0BLEParserBase.CopyToRawData:Data:0x4C
I      0BLEParserBase.CopyToRawData:Data:0x40
I      0BLEParserBase.CopyToRawData:Data:0x4B
I      0BLEParserBase.CopyToRawData:Data:0x4B
I      0BLEParserBase.CopyToRawData:Data:0x4A
I      0BLEParserBase.CopyToRawData:Data:0x4B
I      0BLEParserBase.CopyToRawData:Data:0x48
I      0BLEParserBase.CopyToRawData:Data:0x46
I      0BLEParserBase.CopyToRawData:Data:0x4A
I      0BLEParserBase.CopyToRawData:Data:0x40
I      0BLEParserBase.CopyToRawData:Data:0x45
I      0BLEParserBase.CopyToRawData:Data:0x4B
I      0BLEParserBase.CopyToRawData:Data:0x4D
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My Observations:&lt;/strong&gt;&lt;br /&gt;I could see the Voltage on BLE clearly moves to the changes in input, My question is why it&amp;#39;s not as stable as the bare-metal saadc example when I access it on the above polling method when the input voltage is constant?&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;My other trials:&lt;/strong&gt;&lt;br /&gt;I&amp;#39;ve tried the default saadc peripheral example from the SDK 17.0.2 /17.1&amp;nbsp;&lt;br /&gt;It outputs the value stable on the 52DK via uart. it also responds to the changes to the input voltage accurately.&lt;br /&gt;&lt;br /&gt;But when I add the same code with the BLE stack the output has the same oscillation issue as mentioned in the above output text.&lt;br /&gt;&lt;br /&gt;Thanks for your inputs.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/457220?ContentTypeID=1</link><pubDate>Thu, 23 Nov 2023 16:20:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cbfc2b48-3312-478a-84d8-f76cbb66c0a5</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;There is a bug here, the result is read before the SAADC sample has completed:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;    if (timeout != 0)
    {
        result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/
        5)) / ADC12_COUNTS_PER_VOLT;
    }

    while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) &amp;amp;&amp;amp; timeout &amp;gt; 0)
    {
        timeout--;
    }&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Change to:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;    while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) &amp;amp;&amp;amp; timeout &amp;gt; 0)
    {
        timeout--;
    }
    if (timeout != 0)
    {
        result = ((buffer[0] * 1000L)+(ADC12_COUNTS_PER_VOLT/
        5)) / ADC12_COUNTS_PER_VOLT;
    }&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/457197?ContentTypeID=1</link><pubDate>Thu, 23 Nov 2023 14:25:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f52e3d9e-3013-44a4-b381-720da22f4a9c</guid><dc:creator>helsing</dc:creator><description>&lt;p&gt;Hi Gokulnath,&lt;/p&gt;
[quote user=""]&lt;p&gt;&lt;strong&gt;My Objective:&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;measure the &lt;strong&gt;Li-ion battery voltage(4.2V -100% till 3.6V-0%)&lt;/strong&gt; through an&amp;nbsp;&lt;strong&gt;external resistive divider &amp;amp; internal 0.6v ref voltage&lt;/strong&gt;. (I&amp;#39;m not worried about the current consumption as of this moment. would like to make this concept work &amp;amp; all the other optimisations shall see later&lt;/p&gt;[/quote]
&lt;p&gt;You could try the &lt;em&gt;peripheral/saadc&lt;/em&gt; sample in nRF5 SDK.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
[quote user=""]But the ADC is just measuring some garbage value (random) which is clearly not correct.[/quote]
&lt;p&gt;What does this look like? Would you be able to provide an example? Does the this change if you change the voltage?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
[quote user=""]Thanks, for any valuable input I&amp;#39;m new to NRF.&amp;nbsp;[/quote]
&lt;p&gt;nRF Connect SDK is recommended for new designs. Please see the &lt;a href="https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/nrf-connect-sdk-and-nrf5-sdk-statement#mcetoc_1fcqev3t16"&gt;nRF Connect SDK and nRF5 SDK statement&lt;/a&gt; as well as the &lt;em&gt;nRF Connect SDK Fundamentals&lt;/em&gt; course at &lt;a href="https://academy.nordicsemi.com/"&gt;Nordic Developer Academy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.nordicsemi.com/Products/Development-software/nrf-connect-sdk"&gt;https://www.nordicsemi.com/Products/Development-software/nrf-connect-sdk&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here are some samples for nRF Connect SDK. You could start with &lt;em&gt;simple_blocking&lt;/em&gt; or &lt;em&gt;simple_nonblocking&lt;/em&gt;: &lt;a href="https://github.com/zephyrproject-rtos/hal_nordic/tree/master/nrfx/samples/src/nrfx_saadc"&gt;hal_nordic/nrfx/samples/src/nrfx_saadc at master · zephyrproject-rtos/hal_nordic · GitHub&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/457100?ContentTypeID=1</link><pubDate>Thu, 23 Nov 2023 09:40:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:52086924-b462-4811-91cf-d5b4ea724c68</guid><dc:creator>Gokulnath</dc:creator><description>&lt;p&gt;Hey,&lt;br /&gt;&lt;br /&gt;Yes I&amp;#39;ve verified this on the &lt;strong&gt;nrf52805_bitfields.h&lt;/strong&gt; file (under modules/nrfx/mdk)&amp;nbsp;&lt;br /&gt;&lt;br /&gt;its mentioned as this : &lt;strong&gt;&amp;quot; #define SAADC_CH_PSELP_PSELP_AnalogInput2 (3UL) /*!&amp;lt; AIN2 */&amp;quot;&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;I&amp;#39;ve verified my PCB connections too it&amp;#39;&lt;strong&gt;s under P0.04.&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Voltages to the voltage divider are coming in crisp &amp;amp; voltage drop is similar to theoretical expectations with some milli volt differences.&lt;br /&gt;&lt;br /&gt;Should I continue to debug this? or shall I go back to some tried &amp;amp; tested method example code on Saadc? &lt;strong&gt;(is it available if so please let me know where can i find them. ) may be interrupt on button press is preferred.&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52805: ADC polling mode issue</title><link>https://devzone.nordicsemi.com/thread/457015?ContentTypeID=1</link><pubDate>Wed, 22 Nov 2023 16:34:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7a425061-60c3-434a-aa26-b6d2b33b148f</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Small tip, the SAADC pin numbering can be confusing leading to using the wrong pin; AIN2 is P0.4&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Analog positive and negative input channels have strange numbering:
//  PSELP_NC           0UL  Not connected
//  PSELP_AnalogInput0 1UL  AIN0 P0.02
//  PSELP_AnalogInput1 2UL  AIN1 P0.03
//  PSELP_AnalogInput2 3UL  AIN2 P0.04
//  PSELP_AnalogInput3 4UL  AIN3
//  PSELP_AnalogInput4 5UL  AIN4
//  PSELP_AnalogInput5 6UL  AIN5
//  PSELP_AnalogInput6 7UL  AIN6
//  PSELP_AnalogInput7 8UL  AIN7
//  PSELP_VDD          9UL  VDD&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>