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

Change advertising interval while accelerometer enabling?

Hi,

i m using my custom nrf52832 beacon.For Battery power, i used accelerometer.i trying to change advertising interval  for non connectable BLE device while accelerometer enable.In IDLE mode i set advertising interval is 5000ms.when  accelerometer is enabled, i changed advertising interval to 500ms for next 5 seconds then back to IDLE mode.My question is while in interrupt mode 350 uA current is taking (advertising interval 500ms).

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "app_timer.h"
#include "nrf_drv_clock.h"
#include "ble_advdata.h"
#include "bsp.h"
#include "nordic_common.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_drv_gpiote.h"
#include "boards.h"
#include "nrf_drv_twi.h"
#include "LIS3DH.h"
//#include "nrf_drv_saadc.h"
//#include "nrf_drv_ppi.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
 
#define APP_BLE_CONN_CFG_TAG 1                                              // Tag identifying the BLE configuration.    
#define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(5000, UNIT_0_625_MS)      // iBeacon specifies an advertising interval of 100ms
#define NON_CONNECTABLE_ADV_INTERVAL_FAST  MSEC_TO_UNITS(1000, UNIT_0_625_MS)
#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 0x004C
#define DEAD_BEEF 0xDEADBEEF                                                // Value used as error code on stack dump

/*Pin Congiguration*/
#define NURSE_CALL 13
#define ACCEL_CALL 7
/* Number of possible TWI addresses. */
#define TWI_ADDRESSES      127

APP_TIMER_DEF(my_timer);
APP_TIMER_DEF(fast_my_timer);

uint32_t mac_addr[];                                                        
uint8_t service_uid[17];
uint8_t *service_uid_pointer;
uint8_t m_beacon_info1[APP_BEACON_INFO_LENGTH]={0};
uint8_t serial_number[4];
uint32_t test_sno;
bool aid_flag=false;
bool accel_flag=false;
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. 
bool is_advertising = false;
/* Indicates if operation on TWI has ended. */

/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(0);

 /*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
            }
};

void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) {
  app_error_handler(DEAD_BEEF, line_num, p_file_name);
}

/** Initializing the Advertising.**/
static void advertising_init(uint16_t interval) {
  uint32_t err_code;
  ble_advdata_t advdata;
  uint32_t pin_value;
  uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
/* Beacon Configuration*/
  ble_advdata_manuf_data_t manuf_specific_data;
  manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
  m_beacon_info1[0]=APP_DEVICE_TYPE;                       
  m_beacon_info1[1]=APP_ADV_DATA_LENGTH;
  /* service id*/
  for(int i=5;i>1;i--)
  {
    m_beacon_info1[i]=*service_uid_pointer++;
  }
  //m_beacon_info1[6]=0x00; // Aided
  m_beacon_info1[7]=0xff;                                  //Reserved id
  m_beacon_info1[8]=0xff;                                  // reserved id                                
  m_beacon_info1[18]=0x54;                                 //Major 1st byte
  m_beacon_info1[19]=0x57;                                 //Major 2nd byte
  m_beacon_info1[20]=0x4F;                                 //Minor 1st byte
  m_beacon_info1[21]=0x54;                                  //Minor  2nd byte
  m_beacon_info1[22]=0xC3;                                 //Rssi @1m
  manuf_specific_data.data.p_data = (uint8_t *)m_beacon_info1;
  manuf_specific_data.data.size = APP_BEACON_INFO_LENGTH;
  // Build and set advertising data.
  memset(&advdata, 0, sizeof(advdata));
  advdata.name_type = BLE_ADVDATA_NO_NAME;
  advdata.flags = flags;
  advdata.p_manuf_specific_data = &manuf_specific_data;
  // Initialize advertising parameters.
  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;                                               //Filter policy
  m_adv_params.interval = interval;
  m_adv_params.duration = 0;                                                                     // Never time out.
  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);
}
static void advertising_init_fast(void) {
  uint32_t err_code;
  ble_advdata_t advdata;
  uint32_t pin_value;
  uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
/* Beacon Configuration*/
  ble_advdata_manuf_data_t manuf_specific_data;
  manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
  m_beacon_info1[0]=APP_DEVICE_TYPE;                       
  m_beacon_info1[1]=APP_ADV_DATA_LENGTH;
  /* service id*/
  for(int i=5;i>1;i--)
  {
    m_beacon_info1[i]=*service_uid_pointer++;
  }
  //m_beacon_info1[6]=0x00; // Aided
  m_beacon_info1[7]=0xff;                                  //Reserved id
  m_beacon_info1[8]=0xff;                                  // reserved id                                
  m_beacon_info1[18]=0x54;                                 //Major 1st byte
  m_beacon_info1[19]=0x57;                                 //Major 2nd byte
  m_beacon_info1[20]=0x4F;                                 //Minor 1st byte
  m_beacon_info1[21]=0x54;                                  //Minor  2nd byte
  m_beacon_info1[22]=0xC3;                                 //Rssi @1m
  manuf_specific_data.data.p_data = (uint8_t *)m_beacon_info1;
  manuf_specific_data.data.size = APP_BEACON_INFO_LENGTH;
  // Build and set advertising data.
  memset(&advdata, 0, sizeof(advdata));
  advdata.name_type = BLE_ADVDATA_NO_NAME;
  advdata.flags = flags;
  advdata.p_manuf_specific_data = &manuf_specific_data;
  // Initialize advertising parameters.
  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;                                               //Filter policy
  m_adv_params.interval = NON_CONNECTABLE_ADV_INTERVAL_FAST;
  m_adv_params.duration = 0;                                                                     // Never time out.
  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);
}
/**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);
  err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
  APP_ERROR_CHECK(err_code);
}

void device_name_get(void) {
  memcpy(serial_number,(uint32_t*)0x10001084,4);
  mac_addr[0]=NRF_FICR->DEVICEADDR0; 
  test_sno = test_sno | (serial_number[0] <<24)|(serial_number[1] <<16)|(serial_number[2] <<8)|(serial_number[3]);
  if (test_sno != 0xFFFF7FFFF)
  {   
    for(int i=0;i<4;i++)
    {
     service_uid[i]=serial_number[i];
//     NRF_LOG_INFO("S.NO:%2X",service_uid[i]);
    }
  }
  else
   {
     for(int i=0;i<4;i++){
        service_uid[i]=(uint8_t)((mac_addr[0])>>(8*i));
//        NRF_LOG_INFO("MAC:%2X",service_uid[i]);
      }
   }
service_uid_pointer=&service_uid;
}

/*Initializing the BLE stack.*/
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.
  // 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);
}

/** 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();
}

/**Initializing LEDs. */
static void leds_init(void) {
  ret_code_t err_code = bsp_init(BSP_INIT_LEDS, NULL);
  APP_ERROR_CHECK(err_code);
}

/** 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);
}

static void aid_call_timeout_handler(void * p_context)
{
      //nrf_gpio_pin_clear(17);
      ret_code_t err_code;
     err_code = sd_ble_gap_adv_stop(m_adv_handle);
     accel_flag=false;
     device_name_get();
     m_beacon_info1[6]=0x00; 
    // m_adv_params.interval=NON_CONNECTABLE_ADV_INTERVAL_FAST;
     advertising_init(5000);
     advertising_start();
}

static void accel_timeout_handler(void * p_context)
{
//     nrf_gpio_pin_clear(17);
     accel_flag=false;
     ret_code_t err_code;
     err_code = sd_ble_gap_adv_stop(m_adv_handle);
     device_name_get();
     //m_adv_params.interval=NON_CONNECTABLE_ADV_INTERVAL; 
     advertising_init(5000);
     advertising_start();
}

/**@brief Function for initializing timers. */
static void timers_init(void)
{
    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);
    err_code=app_timer_create(&my_timer, APP_TIMER_MODE_SINGLE_SHOT, aid_call_timeout_handler);  //advertise normally after 5 seconds
    APP_ERROR_CHECK(err_code);
    err_code=app_timer_create(&fast_my_timer, APP_TIMER_MODE_SINGLE_SHOT, accel_timeout_handler);  //advertise normally after 5 seconds
    APP_ERROR_CHECK(err_code);
}

/*Function for handling the idle state (main loop).
 *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();
  }
}

/*Button Handler for aided call*/
void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{  
 // printf("accel");
  if(aid_flag==false)
  { 
    aid_flag=true;
  }
}

/* Accelerometer handler*/
void fast_advertise(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
//nrf_gpio_pin_set(17);
if(accel_flag==false)
{
 accel_flag=true;
}
}
/*@brief Function starting the internal LFCLK oscillator.*/
static void lfclk_request(void)
{
    ret_code_t err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
    nrf_drv_clock_lfclk_request(NULL);
}

/* Gpio Initialisation*/
static void gpio_init(void)
{
   ret_code_t err_code;
   err_code = nrf_drv_gpiote_init();
   APP_ERROR_CHECK(err_code);
   nrf_drv_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
   in_config.pull = NRF_GPIO_PIN_PULLUP;
   err_code = nrf_drv_gpiote_in_init(NURSE_CALL, &in_config, in_pin_handler);
   APP_ERROR_CHECK(err_code);
   err_code = nrf_drv_gpiote_in_init(ACCEL_CALL, &in_config, fast_advertise);
   APP_ERROR_CHECK(err_code);
   nrf_drv_gpiote_in_event_enable(NURSE_CALL, true);
   nrf_drv_gpiote_in_event_enable(ACCEL_CALL, true);
}
/*I2C initialise*/
void twi_init(void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_lis3dh_config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_lis3dh_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

void LIS3DH_write(uint8_t addr, uint8_t wdata)
{
    ret_code_t ret;
	
    uint8_t tx_data[2] = {addr, wdata};
    ret=nrf_drv_twi_tx(&m_twi, LIS3DH_SLAVE_ADDRESS, tx_data, sizeof(tx_data), false);
//    return ret;
}

uint8_t LIS3DH_read(uint8_t addr)
{
	ret_code_t ret;
	static uint8_t receive_data;
	do
    {
      
       ret = nrf_drv_twi_tx(&m_twi, LIS3DH_SLAVE_ADDRESS, &addr, 1, true);
       if(NRF_SUCCESS == ret)
       {

         // printf("twi\n");
           //break;
       }
       ret = nrf_drv_twi_rx(&m_twi, LIS3DH_SLAVE_ADDRESS, &receive_data, 1);
      
    }while(0);
    //printf("device:%02X",receive_data);
    return receive_data;
}


/*LIS3DH INTIALISE*/
void init_LIS3DH(void)
{
    // configurations for control registers
    
//    printf("accel_init\n");
   LIS3DH_write(REG_CTRL_REG1, 0x57);      // Turn on the sensor with ODR = 10Hz normal mode.
   // LIS3DH_write(REG_CTRL_REG1, 0x08);
    LIS3DH_write(REG_CTRL_REG2, 0x01);      // High-pass filter (HPF) enabled with 0.2Hz cut-off frequency for INT1 (AOI1) interrupt generation only.
    LIS3DH_write(REG_CTRL_REG3, 0x40);      // ACC AOI1 interrupt signal is routed to INT1 pin.
    LIS3DH_write(REG_CTRL_REG4, 0x88);      // Full Scale = +/-2 g with BDU and HR bits enabled.
    LIS3DH_write(REG_CTRL_REG5, 0x00);      // Default value. Interrupt signals on INT1 pin is not latched. Users don’t need to read the INT1_SRC register to clear the interrupt signal.
   
    // configurations for wakeup and motionless detection
    LIS3DH_write(REG_INT1_THS, 0x08);         // Threshold (THS) = 8LSBs * 15.625mg/LSB = 125mg.
    LIS3DH_write(REG_INT1_DURATION, 0x32);    // Duration = 50LSBs * (1/10Hz) = 5s.
    LIS3DH_write(REG_INT1_CFG, 0x95);         // Enable XLIE, YLIE and ZLIE interrupt generation, AND logic. It means that the interrupt will be generated when X and Y and Z axis acceleration is within the ±THS threshold simultaneously. 
}

/*Main Loop */
int main(void) 
{
  // Initialize.
  uint16_t i;
//  nrf_gpio_cfg_output(17);
  lfclk_request();
//log_init();
  nrf_drv_clock_init();
  NRF_POWER->DCDCEN = 1;
  device_name_get();
  timers_init();
  power_management_init();
  ble_stack_init();
  twi_init();
  init_LIS3DH();
  advertising_init(5000);
  device_name_get();
  gpio_init();
  sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, BLE_GAP_TX_POWER_ROLE_ADV, 0);     //Set transmission Power
  // Start execution.
  advertising_start();
  // Enter main loop.
 for (;;)
  {
  idle_state_handle();
  LIS3DH_read(0x2E);
  if(aid_flag==true)      // Nurse aided
   {
     ret_code_t err_code;
     err_code = sd_ble_gap_adv_stop(m_adv_handle);
     device_name_get();
     m_beacon_info1[6]=0x03; 
     advertising_init(500);
     advertising_start(); 
     aid_flag=false; 
     app_timer_start(my_timer, APP_TIMER_TICKS(5000), NULL);
 
   }
  if(accel_flag==true)
  {
     ret_code_t err_code;
     err_code = sd_ble_gap_adv_stop(m_adv_handle);
     device_name_get();
     advertising_init(100);
     nrf_delay_ms(10);
     advertising_start();
     app_timer_start(fast_my_timer, APP_TIMER_TICKS(5000), NULL);
  } 
 }
}

/**
 * @}
 */

Parents Reply Children
No Data
Related