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

Low Power Mode using SAADC with ble_app_beacon

Hello !!

I have custom board on nrf52832 having 10 buttons which is pull down by default. I have achieved 22uA after modifying the ble_app_beacon example to broadcast when button is pressed.I am also having coin cell with the custom board so i want to check the battery voltage so that i could indicate the battery level (2 conditons i.e <10% & >10% ) using bi-colour led. 

I have modified ble_app_beacon as per requirement and then integrated SAADC example with modified ble_app_beacon example. I am now getting more than 2 mA current consumption.

So, If anyone could help me with the code so that I could monitor the battery (on any interval) to indicate battery percentage. I am also attaching the main code so that it would be more understandable. My requirement is 3uA when there is no broadcasting.

/**
 * Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 *
 * @defgroup ble_sdk_app_beacon_main main.c
 * @{
 * @ingroup ble_sdk_app_beacon
 * @brief Beacon Transmitter Sample Application main file.
 *
 * This file contains the source code for an Beacon transmitter sample application.
 */

#include <stdbool.h>
#include <stdint.h>
#include "nordic_common.h"
#include "bsp.h"
#include "nrf_soc.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "ble_advdata.h"
#include "app_timer.h"
#include "nrf_drv_clock.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_drv_saadc.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
#include "boards.h"
#include "nrf.h"
#include "nrf_delay.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

/*****  Broadcast Parameters *******/

#define DEVICE_NAME                     "BLE_APP_BEACON"
#define APP_BLE_CONN_CFG_TAG            1                                  /**< A tag identifying the SoftDevice BLE configuration. */
#define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(400, UNIT_0_625_MS)  /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */

#define APP_ADV_DATA_LENGTH             0x15                               /**< Length of manufacturer specific data in the advertisement. */
#define APP_DEVICE_TYPE                 0x02                               /**< 0x02 refers to Beacon. */
#define APP_COMPANY_IDENTIFIER          0x0059                             /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */

#define DEAD_BEEF                       0xDEADBEEF                    /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
#define HIGH 1
#define LOW  0

static ble_gap_adv_params_t m_adv_params;                                  /**< Parameters to be passed to the stack when starting advertising. */
static uint8_t              m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
static uint8_t              m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */

uint16_t remote_led_indication;

static uint8_t      packet_buf;          /****** TX buffer for buttons ******/


/******    ADC parameters  *********/
#define SAMPLES_IN_BUFFER 1

volatile uint8_t state = 1;
static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(1);
static nrf_saadc_value_t     m_buffer_pool[2][SAMPLES_IN_BUFFER];
static nrf_ppi_channel_t     m_ppi_channel;
//static uint32_t              m_adc_evt_counter;

#define ADC_REF_VOLTAGE_IN_MILLIVOLTS   600                                     /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
#define ADC_PRE_SCALING_COMPENSATION    6                                       /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/
//#define DIODE_FWD_VOLT_DROP_MILLIVOLTS  270                                   /**< Typical forward voltage drop of the diode . */
#define ADC_RES_10BIT                   1024                                    /**< Maximum digital value for 10-bit ADC conversion. */
#define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE) \
        ((((ADC_VALUE) *ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION)

void timer_handler(nrf_timer_event_t event_type, void * p_context)
{
}

void saadc_sampling_event_init(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);
    APP_ERROR_CHECK(err_code);

    /* setup m_timer for compare event every 400ms */
    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 400);
    nrf_drv_timer_extended_compare(&m_timer,
                                   NRF_TIMER_CC_CHANNEL0,
                                   ticks,
                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                   false);
    nrf_drv_timer_enable(&m_timer);

    uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
                                                                                NRF_TIMER_CC_CHANNEL0);
    uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();

    /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
    err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
                                          timer_compare_event_addr,
                                          saadc_sample_task_addr);
    APP_ERROR_CHECK(err_code);
}

void saadc_sampling_event_enable(void)
{
    ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);

    APP_ERROR_CHECK(err_code);
}

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        ret_code_t err_code;
        nrf_saadc_value_t adc_result;
        uint16_t batt_lvl_in_milli_volts;
        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);

        int i;

        //NRF_LOG_INFO("ADC event number: %d", (int)m_adc_evt_counter);

        for (i = 0; i < SAMPLES_IN_BUFFER; i++)
        {
          adc_result=p_event->data.done.p_buffer[0];
         
          batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result);

        }
        remote_led_indication = batt_lvl_in_milli_volts;  
        //m_adc_evt_counter++;
    }
}

void saadc_init(void)
{
    ret_code_t err_code;
    nrf_saadc_channel_config_t channel_config =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);

    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);

}

/**@brief Function for the GAP initialization.
 *
 * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
 *          the device. It also sets the permissions and appearance.
 */
static void gap_params_init(void)
{
   uint32_t err_code;
   ble_gap_conn_sec_mode_t     sec_mode;
   BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
   err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME,
   strlen(DEVICE_NAME));
   APP_ERROR_CHECK(err_code);
}

/**@brief Struct that contains pointers to the encoded advertising data. */
static ble_gap_adv_data_t m_adv_data =
{
    .adv_data =
    {
        .p_data = m_enc_advdata,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    },
    .scan_rsp_data =
    {
        .p_data = NULL,
        .len    = 0

    }
};

/**@brief Callback function for asserts in the SoftDevice.
 *
 * @details This function will be called in case of an assert in the SoftDevice.
 *
 * @warning This handler is an example only and does not fit a final product. You need to analyze
 *          how your product is supposed to react in case of Assert.
 * @warning On assert from the SoftDevice, the system can only recover on reset.
 *
 * @param[in]   line_num   Line number of the failing ASSERT call.
 * @param[in]   file_name  File name of the failing ASSERT call.
 */
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
    app_error_handler(DEAD_BEEF, line_num, p_file_name);
}

/**@brief Function for initializing the Advertising functionality.
 *
 * @details Encodes the required advertising data and passes it to the stack.
 *          Also builds a structure to be passed to the stack when starting advertising.
 */

static void advertising_data_update(void)
{
    uint32_t      err_code;
    ble_advdata_t advdata;
    uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;

    ble_advdata_manuf_data_t manuf_specific_data;

    manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
    manuf_specific_data.data.p_data = (uint8_t *) &packet_buf;
    manuf_specific_data.data.size   = sizeof(packet_buf);
    advdata.p_manuf_specific_data = &manuf_specific_data;

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));
    //advdata.name_type             = BLE_ADVDATA_NO_NAME;
    advdata.name_type             = BLE_ADVDATA_FULL_NAME;
    advdata.flags                 = flags;
    advdata.p_manuf_specific_data = &manuf_specific_data;

    // Initialize advertising parameters (used when starting advertising).
    memset(&m_adv_params, 0, sizeof(m_adv_params));

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
    m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.duration        = 400;       // Broadcast for 4 sec.

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
    APP_ERROR_CHECK(err_code);
}
/**@brief Function for starting advertising.
 */
static void advertising_start(void)
{
    ret_code_t err_code;

    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    APP_ERROR_CHECK(err_code);

/**** LED indication while advertising ****/
    if (remote_led_indication > ("%d", 1920)){
        nrf_gpio_pin_write(LED_1, LOW);   // Green Led will Blink on less than 10% battery
        nrf_delay_ms(50);

        nrf_gpio_pin_write(LED_1, HIGH);
        nrf_delay_ms(50);

       }

    if (remote_led_indication < ("%d", 1920)){
        nrf_gpio_pin_write(LED_2, LOW);   // Red Led will Blink on more than 10% battery
        nrf_delay_ms(50);

        nrf_gpio_pin_write(LED_2, HIGH);  
        nrf_delay_ms(50);

       }

    //err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
    //APP_ERROR_CHECK(err_code);
}


/**@brief Function for starting advertising.
 */
static void advertising_stop()
{
    ret_code_t err_code;

    err_code = sd_ble_gap_adv_stop(m_adv_handle);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing the BLE stack.
 *
 * @details Initializes the SoftDevice and the BLE event interrupt.
 */
static void ble_stack_init(void)
{
    ret_code_t err_code;
    err_code = nrf_sdh_enable_request();
 
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing logging. */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}

/**@brief Function for initializing LEDs. */
static void leds_init(void)
{
    ret_code_t err_code = bsp_init(BSP_INIT_LEDS, NULL);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing timers. */
static void timers_init(void)
{
    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing power management.
 */
static void power_management_init(void)
{
    ret_code_t err_code;
    err_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for handling the idle state (main loop).
 *
 * @details If there is no pending log operation, then sleep until next the next event occurs.
 */
static void idle_state_handle(void)
{
    if (NRF_LOG_PROCESS() == false)
    {
        nrf_pwr_mgmt_run();
    }
}

/**@brief Function for handling bsp events.
 */
void bsp_evt_handler(bsp_event_t evt)
{ 
    switch (evt)
    {
          case BSP_EVENT_KEY_0:
          packet_buf = BSP_EVENT_KEY_0;
          break;

          case BSP_EVENT_KEY_1:
          packet_buf = BSP_EVENT_KEY_1;
          break;

          case BSP_EVENT_KEY_2:
          packet_buf = BSP_EVENT_KEY_2;
          break;

          case BSP_EVENT_KEY_3:
          packet_buf = BSP_EVENT_KEY_3;
          break;

          case BSP_EVENT_KEY_4:
          packet_buf = BSP_EVENT_KEY_4;
          break;
           
          case BSP_EVENT_KEY_5:
          packet_buf = BSP_EVENT_KEY_5;
          break;
   
          case BSP_EVENT_KEY_6:
          packet_buf = BSP_EVENT_KEY_6;
          break;
      
          case BSP_EVENT_KEY_7:
          packet_buf = BSP_EVENT_KEY_7;
          break;

          case BSP_EVENT_KEY_8:
          packet_buf = BSP_EVENT_KEY_8;
          break;
   
          case BSP_EVENT_KEY_9:
          packet_buf = BSP_EVENT_KEY_9;
          break;
      
          case BSP_EVENT_KEY_10:
          packet_buf = BSP_EVENT_KEY_10;
          break;  
    }
   
    NRF_LOG_INFO("%u", packet_buf);
    (void)sd_ble_gap_adv_stop(m_adv_handle);
    advertising_data_update();
    advertising_start();
}


/**
 * @brief Function for application main entry.
 */
int main(void)
{
    NRF_POWER->DCDCEN = 1;    
    uint32_t err_code = NRF_SUCCESS; 
 
    // Initialize.
    nrf_pwr_mgmt_init();
    //log_init();
    timers_init();
    //leds_init();
    //power_management_init();
    ble_stack_init();
    gap_params_init();
    //advertising_init();
    advertising_data_update();
    
    
    err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_evt_handler);
    APP_ERROR_CHECK(err_code);

    saadc_init();
    saadc_sampling_event_init();
    saadc_sampling_event_enable();


    // Start execution.
    NRF_LOG_INFO("Beacon example started.");
    advertising_start();

    // Enter main loop.
    for(;;)
    {
        idle_state_handle();
    }
}


/**
 * @}
 */

I would appreciate any help!!!

Thanks!!!

Parents
  • Hello,

    I would recommend using a low power app timer instance to trigger the periodic sampling. The high frequency TIMER which you have currently selected will increase the idle current to around ~600 uA because it requires the HF oscillator to be kept active in idle.

    The Softdevice Radio Notification signals is another trigger source you could use. One advantage with using radio notification signals is that you can more easily make sure you are not sampling while the RADIO is active, which might be needed considering that battery voltage of a coincell tend to drop significantly under load.

    Attached is an example I put together that uses the app timer to trigger the sampling. Let me know if you are interested in using the radio notifications signals instead.

    2766.nRF5_SDK17.0.2_ble_app_beacon_lp_saadc.zip

  • Hi Vidar!!

    Thank you for your reply!! The code worked perfect!! Also modifying with my custom board it is working perfectly. 

    Now the thing is it is consuming ~ 22 uA (fluctuating) on idle state but I want to measure the battery level when the broadcasting is happening and stop else so that it will not consume any current. Any suggestion how to uninitialised it? so that it should go original idle power consumption. Also what should be interval for measuring the voltage to keep track of battery level?

  • Hi!

    techietech said:
    The very first start of board giving 1-3uA and when the button is pushed it is start consuming ~ 22 uA (fluctuating) on no activity. Any suggestion here?

    The idle current should drop back to 1-3 uA shortly after the button(s) have been released. Does that not happen in your case?

    techietech said:
    Then got the result of ~140uA on new activity after 20 seconds.

    The device is should enter system OFF (deep sleep) when you let this standby timer expire, and the OFF current should only be around 600 nA. Is it possible that you may have a floating input? Either way, please check if you get the same result if you remove the initialization of your button inputs.

  • Hi!

    Is it possible that you may have a floating input? Either way, please check if you get the same result if you remove the initialization of your button inputs.

    If I remove the initialisation of button input then it is going to sleep mode and i guess, there is no floating point as i pull down.

    The device is should enter system OFF (deep sleep) when you let this standby timer expire,

    Will it harm to my program further?

    i am attaching my code below so that if you could check what i am missing

    /**
     * Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     *
     * @defgroup ble_sdk_app_beacon_main main.c
     * @{
     * @ingroup ble_sdk_app_beacon
     * @brief Beacon Transmitter Sample Application main file.
     *
     * This file contains the source code for an Beacon transmitter sample application.
     */
    
    /******** Ble_beacon_remote **********/
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "nordic_common.h"
    #include "bsp.h"
    #include "nrf_soc.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "ble_advdata.h"
    #include "app_timer.h"
    #include "nrf_pwr_mgmt.h"
    #include "nrf_drv_clock.h"
    #include "nrf_drv_saadc.h"
    #include "nrf_drv_ppi.h"
    #include "nrf_drv_timer.h"
    #include "boards.h"
    #include "nrf.h"
    #include "nrf_delay.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #define DEVICE_NAME                     "Device_Name"
    #define APP_BLE_CONN_CFG_TAG            1                                  /**< A tag identifying the SoftDevice BLE configuration. */
    
    #define BATTERY_LEVEL_MEAS_INTERVAL     APP_TIMER_TICKS(5000)              /**< Battery level measurement interval (ticks). */
    
    #define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(100, UNIT_0_625_MS)  /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */
    
    #define APP_BEACON_INFO_LENGTH          0x17                               /**< Total length of information advertised by the Beacon. */
    #define APP_ADV_DATA_LENGTH             0x15                               /**< Length of manufacturer specific data in the advertisement. */
    #define APP_DEVICE_TYPE                 0x02                               /**< 0x02 refers to Beacon. */
    #define APP_COMPANY_IDENTIFIER          0x0059  
    
    
    #define ADC_REF_VOLTAGE_IN_MILLIVOLTS   600                               /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
    #define ADC_PRE_SCALING_COMPENSATION    6                                 /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/
    #define DIODE_FWD_VOLT_DROP_MILLIVOLTS  270                               /**< Typical forward voltage drop of the diode . */
    #define ADC_RES_10BIT                   1024                              /**< Maximum digital value for 10-bit ADC conversion. */
    
    uint16_t remote_led_indication;
    static uint8_t      packet_buf[2];          /****** TX buffer for buttons ******/
    
    /**@brief Macro to convert the result of ADC conversion in millivolts.
     *
     * @param[in]  ADC_VALUE   ADC result.
     *
     * @retval     Result converted to millivolts.
     */
    #define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\
            ((((ADC_VALUE) * ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION)
    
    #define DEAD_BEEF                       0xDEADBEEF                         /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    #define HIGH        1
    #define LOW         0
    
    static ble_gap_adv_params_t m_adv_params;                                  /**< Parameters to be passed to the stack when starting advertising. */
    static uint8_t              m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
    static uint8_t              m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */
    
    static nrf_saadc_value_t m_adc_buf;
    
    APP_TIMER_DEF(m_battery_timer_id);                                         /**< Battery timer. */
    
    /**@brief Function for the GAP initialization.
    212 
     *
    213 
     * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
    214 
     *          the device. It also sets the permissions and appearance.
    215 
     */ 
    static void gap_params_init(void)
    {
       uint32_t err_code;
       ble_gap_conn_sec_mode_t     sec_mode;
       BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
       err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME,
    
       strlen(DEVICE_NAME));
     
       APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Struct that contains pointers to the encoded advertising data. */
    static ble_gap_adv_data_t m_adv_data =
    {
        .adv_data =
        {
            .p_data = m_enc_advdata,
            .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
        },
        .scan_rsp_data =
        {
            .p_data = NULL,
            .len    = 0
    
        }
    };
    
    /**@brief Callback function for asserts in the SoftDevice.
     *
     * @details This function will be called in case of an assert in the SoftDevice.
     *
     * @warning This handler is an example only and does not fit a final product. You need to analyze
     *          how your product is supposed to react in case of Assert.
     * @warning On assert from the SoftDevice, the system can only recover on reset.
     *
     * @param[in]   line_num   Line number of the failing ASSERT call.
     * @param[in]   file_name  File name of the failing ASSERT call.
     */
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(DEAD_BEEF, line_num, p_file_name);
    }
    
    
    /**@brief Function for handling the ADC interrupt.
     *
     * @details  This function will fetch the conversion result from the ADC, convert the value into
     *           percentage and send it to peer.
     */
    void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event)
    {
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
        {
            nrf_saadc_value_t adc_result;
            uint16_t batt_lvl_in_milli_volts;
            uint8_t percentage_batt_lvl;
            uint32_t err_code;
    
            adc_result = p_event->data.done.p_buffer[0];
    
            batt_lvl_in_milli_volts =
                ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS;
    
            NRF_LOG_INFO("Battery Level Measurement : %d [mV]", batt_lvl_in_milli_volts);
            
            remote_led_indication = batt_lvl_in_milli_volts;
        }
        else if (p_event->type == NRF_DRV_SAADC_EVT_CALIBRATEDONE)
        {
            NRF_LOG_INFO("SAADC calibration complete");
        }
    }
    
    
    /**@brief Function for handling the Battery measurement timer timeout.
     *
     * @details This function will be called each time the battery level measurement timer expires.
     *
     * @param[in] p_context  Pointer used for passing some arbitrary information (context) from the
     *                       app_start_timer() call to the timeout handler.
     */
    static void battery_level_meas_timeout_handler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
        
        ret_code_t err_code = nrf_drv_saadc_buffer_convert(&m_adc_buf, 1);
        APP_ERROR_CHECK(err_code);
        
        err_code = nrf_drv_saadc_sample();
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing the Advertising functionality.
     *
     * @details Encodes the required advertising data and passes it to the stack.
     *          Also builds a structure to be passed to the stack when starting advertising.
     */
    static void advertising_data_update(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        uint8_t       flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
        ble_advdata_manuf_data_t manuf_specific_data;
    
        manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
        manuf_specific_data.data.p_data = (uint8_t *) &packet_buf;
        manuf_specific_data.data.size   = sizeof(packet_buf);
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type             = BLE_ADVDATA_FULL_NAME;
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 400;       // Broadcast for 4 sec.
    
        err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        ret_code_t err_code;
    
        err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
        APP_ERROR_CHECK(err_code);
    
    /**** LED indication while advertising ****/
        if (remote_led_indication > ("%d", 1920)){
            nrf_gpio_pin_write(LED_1, LOW);  
            nrf_delay_ms(50);
    
            nrf_gpio_pin_write(LED_1, HIGH);
            nrf_delay_ms(50);
     
            NRF_LOG_INFO("More than 10 percent battery level");
           }
    
        if (remote_led_indication < ("%d", 1920)){
            nrf_gpio_pin_write(LED_2, LOW);  
            nrf_delay_ms(50); 
    
            nrf_gpio_pin_write(LED_2, HIGH);   
            nrf_delay_ms(50);
    
            NRF_LOG_INFO("Less than 10 percent battery level");
           }
    }
    
    /**@brief Function for starting advertising.
     */
    static void advertising_stop()
    {
        ret_code_t err_code;
     
        err_code = sd_ble_gap_adv_stop(m_adv_handle);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for handling bsp events.
    412 
     */
    
    void bsp_evt_handler(bsp_event_t evt)
    {
        switch (evt) 
        {
              case BSP_EVENT_KEY_0:
              packet_buf[0] = BSP_EVENT_KEY_0;
              packet_buf[1]++;
              break;
    
              case BSP_EVENT_KEY_1: 
              packet_buf[0] = BSP_EVENT_KEY_1;
              packet_buf[1]++;
              break;
    
              case BSP_EVENT_KEY_2: 
              packet_buf[0] = BSP_EVENT_KEY_2;
              packet_buf[1]++;
              break;
    
              case BSP_EVENT_KEY_3: 
              packet_buf[0] = BSP_EVENT_KEY_3;
              packet_buf[1]++;
              break;
     
              case BSP_EVENT_KEY_4: 
              packet_buf[0] = BSP_EVENT_KEY_4;
              packet_buf[1]++;
              break;
              
              case BSP_EVENT_KEY_5:
              packet_buf[0] = BSP_EVENT_KEY_5;
              packet_buf[1]++;
              break;
      
              case BSP_EVENT_KEY_6: 
              packet_buf[0] = BSP_EVENT_KEY_6;
              packet_buf[1]++;
              break;
          
              case BSP_EVENT_KEY_7:
              packet_buf[0] = BSP_EVENT_KEY_7;
              packet_buf[1]++;
              break;
    
              case BSP_EVENT_KEY_8: 
              packet_buf[0] = BSP_EVENT_KEY_8;
              packet_buf[1]++;
              break; 
    
              case BSP_EVENT_KEY_9: 
              packet_buf[0] = BSP_EVENT_KEY_9;
              packet_buf[1]++;
              break;
          
              case BSP_EVENT_KEY_10:
              packet_buf[0] = BSP_EVENT_KEY_10;
              packet_buf[1]++;
              break;  
        }
    
        NRF_LOG_INFO("%u", packet_buf);
        (void)sd_ble_gap_adv_stop(m_adv_handle);
        advertising_data_update();
        advertising_start();
    }
    
    
    /**@brief Function for initializing logging. */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    /**@brief Function for initializing timers. */
    static void timers_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
     
        // Create timers.
        err_code = app_timer_create(&m_battery_timer_id,
                                    APP_TIMER_MODE_REPEATED,
                                    battery_level_meas_timeout_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for starting application timers.
     */
    static void application_timers_start(void)
    {
        ret_code_t err_code;
    
        // Start application timers.
        err_code = app_timer_start(m_battery_timer_id, BATTERY_LEVEL_MEAS_INTERVAL, NULL);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing power management.
     */
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for configuring ADC to do battery level conversion.
     */
    static void adc_configure(void)
    {
        ret_code_t err_code = nrf_drv_saadc_init(NULL, saadc_event_handler);
        APP_ERROR_CHECK(err_code);
    
        nrf_saadc_channel_config_t config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);
    
        config.burst = NRF_SAADC_BURST_ENABLED;
    
        err_code = nrf_drv_saadc_channel_init(0, &config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_calibrate_offset();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the idle state (main loop).
     *
     * @details If there is no pending log operation, then sleep until next the next event occurs.
     */
    static void idle_state_handle(void)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }
    }
    
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        // Initialize.
        timers_init();
        power_management_init();
        ble_stack_init();
        gap_params_init();
        (void)sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);
        advertising_data_update();
    
        uint8_t err_code = NRF_SUCCESS;
        //err_code = bsp_init(BSP_INIT_BUTTONS, bsp_evt_handler);
    
        err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        adc_configure();
    
        // Start execution.
        NRF_LOG_INFO("Beacon example started.");
        application_timers_start();
        advertising_start();
    
        // Enter main loop.
        for (;; )
        {
            idle_state_handle();
        }
    }
    
    
    /**
     * @}
     */

    Thanks!!

  • Hi,

    The chip is powered down in System OFF mode and a wake-up from this mode will lead to a system reset. Is this what you want, or should the chip always stay in System ON mode and do periodic advertising? 

  • Hi!

    I just want to system should be on while advertising on button press and else it should be either on system on sleep mode or system off sleep mode as it's not that much concern as per my requirements. 

    Also system should be always wake up immediately on each button press. If you could review the above code so that you could provide yours suggestions whether if I missed something.

Reply Children
  • Hi,

    It makes sense to use System OFF if the device is expected to stay inactive (i.e. no advertising) for longer periods of time, and that you only rely on the button press as the wake-up source.

    Before entering system OFF you should also make that there is no ongoing SAADC sampling. From the PS:

    Before entering System OFF mode, the user must make sure that all on-going EasyDMA transactions have been completed. This is usually accomplished by making sure that the EasyDMA enabled peripheral is not active when entering System OFF.

  • Hi!

    Thanks for your reply. As you said : 

    Before entering System OFF mode, the user must make sure that all on-going EasyDMA transactions have been completed. This is usually accomplished by making sure that the EasyDMA enabled peripheral is not active when entering System OFF

    1. How could I make sure that in my code that EasyDMA enabled peripheral is inactive? As I mentioned: 

    I enabled this macros in sdk_config.h

    i.e. I am not calling any APIs to enter in system OFF.

    Secondly, I am making two conditions to to show the battery indications i.e. bat_lvl <= 1920mV then LED_1 will toggle & bat_lvl > 1920mV then LED_2 will toggle while button press but it is happening for only one condition i.e. bat_lvl > 1920mV 

    2. Why? related code is below : 

    uint8_t remote_led_indication;
    
    /**@brief Function for handling the ADC interrupt.
     *
     * @details  This function will fetch the conversion result from the ADC, convert the value into
     *           percentage and send it to peer.
     */
    void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event)
    {
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
        {
            nrf_saadc_value_t adc_result;
            uint16_t batt_lvl_in_milli_volts;
            uint8_t percentage_batt_lvl;
            uint32_t err_code;
    
            adc_result = p_event->data.done.p_buffer[0];
    
            batt_lvl_in_milli_volts =
            ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS;
    
            NRF_LOG_INFO("Battery Level Measurement : %d [mV]", batt_lvl_in_milli_volts);
            
            remote_led_indication = batt_lvl_in_milli_volts;
        }
        else if (p_event->type == NRF_DRV_SAADC_EVT_CALIBRATEDONE)
        {
            NRF_LOG_INFO("SAADC calibration complete");
        }
    }
    
    
    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        ret_code_t err_code;
    
        err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
        APP_ERROR_CHECK(err_code);
    
    /**** LED indication while advertising ****/
        if (remote_led_indication >= 1920)){
            nrf_gpio_pin_write(LED_1, LOW);
            nrf_delay_ms(50);
    
            nrf_gpio_pin_write(LED_1, HIGH);
            nrf_delay_ms(50);
            
           }
    
        if (remote_led_indication < 1920){
            nrf_gpio_pin_write(LED_2, LOW);
            nrf_delay_ms(50); 
    
            nrf_gpio_pin_write(LED_2, HIGH);   
            nrf_delay_ms(50);
           }
    }
    

    Thirdly, I was using metal dome push buttons which was pull down (default) on my PCB and the current consumptions result I have shared above.

    Now we have changed it with capSense (Cypress CY8CMBR2110) which is pull up (default) and current consumption is ~ 1.3mA when there is no button pressed and when button is pressed ~ 4.1mA. 

    3. Why this is happening as it should go to system off after time expires ? Do I need to change something in the code to achieve low power mode ?

    4.  Sometimes the nrf52832 chip is resetting I don't know how this is happening now. As it was working perfectly before. I am attaching my pca10040.h below : 

    #ifndef PCA10040_H
    #define PCA10040_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #include "nrf_gpio.h"
    
    // LEDs definitions for PCA10040
    #define LEDS_NUMBER    4
    
    //#define LED_START      17
    #define LED_1          22
    #define LED_2          20
    #define LED_3          19
    #define LED_4          20
    //#define LED_STOP       20
    
    #define LEDS_ACTIVE_STATE 0
    
    #define LEDS_INV_MASK  LEDS_MASK
    
    #define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 }
    
    #define BSP_LED_0      LED_1
    #define BSP_LED_1      LED_2
    #define BSP_LED_2      LED_3
    #define BSP_LED_3      LED_4
    
    #define BUTTONS_NUMBER 11
    
    //#define BUTTON_START   13
    #define BUTTON_1       17
    #define BUTTON_8       7
    #define BUTTON_3       6
    #define BUTTON_4       16
    #define BUTTON_5       15
    #define BUTTON_6       12
    #define BUTTON_7       11
    #define BUTTON_2       10
    #define BUTTON_9       9
    #define BUTTON_10      8
    //#define BUTTON_STOP    16
    #define BUTTON_PULL    NRF_GPIO_PIN_PULLUP
    
    #define BUTTONS_ACTIVE_STATE 0
    
    #define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4, BUTTON_5, BUTTON_6, BUTTON_7, BUTTON_8, BUTTON_9, BUTTON_10}
    
    #define BSP_BUTTON_0   BUTTON_1
    #define BSP_BUTTON_1   BUTTON_2
    #define BSP_BUTTON_2   BUTTON_3
    #define BSP_BUTTON_3   BUTTON_4
    #define BSP_BUTTON_4   BUTTON_5
    #define BSP_BUTTON_5   BUTTON_6
    #define BSP_BUTTON_6   BUTTON_7
    #define BSP_BUTTON_7   BUTTON_8
    #define BSP_BUTTON_8   BUTTON_9
    #define BSP_BUTTON_9   BUTTON_10
    
    
    #define RX_PIN_NUMBER  3
    #define TX_PIN_NUMBER  4
    #define CTS_PIN_NUMBER 7
    #define RTS_PIN_NUMBER 5
    #define HWFC           true
    
    #define SPIS_MISO_PIN   28  // SPI MISO signal.
    #define SPIS_CSN_PIN    12  // SPI CSN signal.
    #define SPIS_MOSI_PIN   25  // SPI MOSI signal.
    #define SPIS_SCK_PIN    29  // SPI SCK signal.
    
    #define SPIM0_SCK_PIN   29  // SPI clock GPIO pin number.
    #define SPIM0_MOSI_PIN  25  // SPI Master Out Slave In GPIO pin number.
    #define SPIM0_MISO_PIN  28  // SPI Master In Slave Out GPIO pin number.
    #define SPIM0_SS_PIN    12  // SPI Slave Select GPIO pin number.
    
    #define SPIM1_SCK_PIN   2   // SPI clock GPIO pin number.
    #define SPIM1_MOSI_PIN  3   // SPI Master Out Slave In GPIO pin number.
    #define SPIM1_MISO_PIN  4   // SPI Master In Slave Out GPIO pin number.
    #define SPIM1_SS_PIN    5   // SPI Slave Select GPIO pin number.
    
    #define SPIM2_SCK_PIN   12  // SPI clock GPIO pin number.
    #define SPIM2_MOSI_PIN  13  // SPI Master Out Slave In GPIO pin number.
    #define SPIM2_MISO_PIN  14  // SPI Master In Slave Out GPIO pin number.
    #define SPIM2_SS_PIN    15  // SPI Slave Select GPIO pin number.
    
    // serialization APPLICATION board - temp. setup for running serialized MEMU tests
    #define SER_APP_RX_PIN              23    // UART RX pin number.
    #define SER_APP_TX_PIN              24    // UART TX pin number.
    #define SER_APP_CTS_PIN             2     // UART Clear To Send pin number.
    #define SER_APP_RTS_PIN             25    // UART Request To Send pin number.
    
    #define SER_APP_SPIM0_SCK_PIN       27     // SPI clock GPIO pin number.
    #define SER_APP_SPIM0_MOSI_PIN      2      // SPI Master Out Slave In GPIO pin number
    #define SER_APP_SPIM0_MISO_PIN      26     // SPI Master In Slave Out GPIO pin number
    #define SER_APP_SPIM0_SS_PIN        23     // SPI Slave Select GPIO pin number
    #define SER_APP_SPIM0_RDY_PIN       25     // SPI READY GPIO pin number
    #define SER_APP_SPIM0_REQ_PIN       24     // SPI REQUEST GPIO pin number
    
    // serialization CONNECTIVITY board
    #define SER_CON_RX_PIN              24    // UART RX pin number.
    #define SER_CON_TX_PIN              23    // UART TX pin number.
    #define SER_CON_CTS_PIN             25    // UART Clear To Send pin number. Not used if HWFC is set to false.
    #define SER_CON_RTS_PIN             2     // UART Request To Send pin number. Not used if HWFC is set to false.
    
    
    #define SER_CON_SPIS_SCK_PIN        27    // SPI SCK signal.
    #define SER_CON_SPIS_MOSI_PIN       2     // SPI MOSI signal.
    #define SER_CON_SPIS_MISO_PIN       26    // SPI MISO signal.
    #define SER_CON_SPIS_CSN_PIN        23    // SPI CSN signal.
    #define SER_CON_SPIS_RDY_PIN        25    // SPI READY GPIO pin number.
    #define SER_CON_SPIS_REQ_PIN        24    // SPI REQUEST GPIO pin number.
    
    #define SER_CONN_CHIP_RESET_PIN     11    // Pin used to reset connectivity chip
    
    
    // Arduino board mappings
    #define ARDUINO_SCL_PIN             27    // SCL signal pin
    #define ARDUINO_SDA_PIN             26    // SDA signal pin
    #define ARDUINO_AREF_PIN            2     // Aref pin
    #define ARDUINO_13_PIN              25    // Digital pin 13
    #define ARDUINO_12_PIN              24    // Digital pin 12
    #define ARDUINO_11_PIN              23    // Digital pin 11
    #define ARDUINO_10_PIN              22    // Digital pin 10
    #define ARDUINO_9_PIN               20    // Digital pin 9
    #define ARDUINO_8_PIN               19    // Digital pin 8
    
    #define ARDUINO_7_PIN               18    // Digital pin 7
    #define ARDUINO_6_PIN               17    // Digital pin 6
    #define ARDUINO_5_PIN               16    // Digital pin 5
    #define ARDUINO_4_PIN               15    // Digital pin 4
    #define ARDUINO_3_PIN               14    // Digital pin 3
    #define ARDUINO_2_PIN               13    // Digital pin 2
    #define ARDUINO_1_PIN               12    // Digital pin 1
    #define ARDUINO_0_PIN               11    // Digital pin 0
    
    #define ARDUINO_A0_PIN              3     // Analog channel 0
    #define ARDUINO_A1_PIN              4     // Analog channel 1
    #define ARDUINO_A2_PIN              28    // Analog channel 2
    #define ARDUINO_A3_PIN              29    // Analog channel 3
    #define ARDUINO_A4_PIN              30    // Analog channel 4
    #define ARDUINO_A5_PIN              31    // Analog channel 5
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif // PCA10040_H
    

    I'd like thank for your kind support above and also I'd also appreciate your soon response for this.

    Thanks

  • Hello,

    1. Do you plan to use the System OFF mode or not? You were enabling the NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED option earlier which will cause the device to enter system OFF if you let it time out.

    2. Try to define 'remote_led_indication' as 'volatile' : volatile uint8_t remote_led_indication

    3. 1.3 mA indicates that the i2c peripheral on the nRF might be staying in receive mode all the time. Or are you utilzing the 'attention/sleep' signal from the Cypress IC to only enable i2c when needed? And I guess the 4 mA is because the CPU is kept running

    4. It's likely caused by an assertion in your code (e.g. when an error code is passed to the APP_ERROR_CHECK() macro, please see the "Error module" documentation for more on this.

  • Hi!

    1. Yes. I have implemented.

    Do you plan to use the System OFF mode or not

    3. I am not using I2C. It is just connected with SCL & SDA lines with nrf52832 and that's why I guess it is consuming current.

    are you utilzing the 'attention/sleep' signal from the Cypress IC to only enable i2c when needed

    Could you provide me any example code so that I could implement cypress capsense button and nrf52832 and then after I could achieve low power mode.

    Thanks 

Related